WebApps Migration JSF 2.2 MyFaces, RichFaces zu Primefaces, REST, JPA 2, JEE7 auf JBoss WildFly 10

Die Motivation

Ein oftmals relevantes Thema, wenn JEE Applikationen migriert werden sollen und die JSF-Applikationen gleich mit migriert werden, ist die Migration von RichFaces oder MyFaces-Implementierungen auf Primefaces. In diesem Blog-Eintrag hier soll dies anhand einer MyFaces JSF 2.2 Beispiel-Applikation bookstore auf die sehr vorteilhafte Primefaces-Technologie beschrieben werden. Die migrierte bookstore-primefaces ermöglicht dann die leichte Pflege von und die Suche nach Produkten bestimmter Kategorien und Bestellungen von Kunden, d. h. diese Beispielapplikation ermöglicht die Bearbeitung und Präsentation der Stammdaten (Kunden), Bestandsdaten (E-Books) und Bewegungsdaten (Abverkaufsdaten) einer Buchhandlung. Hatten die MyFaces-Beispiel-Applikationen noch extra Suchfelder und Schwächen bei der Sortierung der Ergebnislisten, bieten nach der Umstellung die Primefaces-Views das Durchsuchen, Sortieren und eine wählbare Pagination der Ergebnisliste bereits als Komfortfunktionen der robusten, aber stets elegant gestylten, etablierten, optimalen Primefaces Frontend-Technologie und deren Standard Primefaces-Funktionalitäten an.

Die Beispiel-Applikation bookstore-primefaces wird dann wird dann auf den JBoss WildFly 9 Final, WildFly 10 Final und WildFly 11 Final Servern deployt und kann hier getestet werden. Die Verwendung der JBoss WildFly JEE7-Application Server wurde in diesem Blog bereits einmal beschrieben. Dabei liefern die JEE6- und JEE7-Beispielapplikationen hier mit Hilfe eines EJB 3-getriebenen Backends (Session Beans als DAOs, „DAO“-Pattern) unter Anbindung der JPA 2 Entities („Table-Per-Class“-Pattern) mit Hilfe von DTOs über fachliche RESTful ServiceInterfaces oder per Microservices mit Docker, Spring Boot, siehe auch „ServiceBroker“-Pattern hier, die benötigten Daten zur Präsentation und Bearbeitung (Änderung, Löschen, Neuanlage) in den Web-Frontends, welche die WebServices konsumieren („ServiceConsumer“-Pattern).

Erstellung der Beispiel Applikation auf dem Datenmodell

Mittels DBeaver wird das Klassendiagramm der Entities aus den Datenbank-Objekten erstellt und aus diesen, nach dem Anlegen der Datenbank per Hibernate Envers während dem WildFly 10 Undertow Deployment mittels JBoss Forge Eclipse PlugIn im JBoss Developer Studio erst der REST-WebService mit den Endpoints generiert und danach die Primefaces 6 WebApp auf diesem RESTful WebService. Hier das E-R-Diagramm der Buchhandlungs-Datenbank:

E-R-diagram
(E-R-Diagramm der Beispiel-Datenbank „bookstore“ ohne die MySQL-Sequence-Tabellen.)

Dabei darf positiv erwähnt werden, dass man mittels JBoss Forge eine saubere, stringente Architektur in die JEE7-Applikation einbringt, die beim Weiterentwickeln der App sehr hilfreich ist und sowohl die Entwicklungszeit-Performance als auch die Codequalität deutlich steigert. Danke, JBoss Rockstars!

Bei dieser Gelegenheit darf auch das sehr effektive, interessante und erfolgreiche Seminar

“TDD mit Java”

von Binaris Informatik erwähnt werden.

Es werden in der pom.xml die folgenden Maven Dependencies identifiziert, verwendet und importiert:

Maven JEE 7 JBoss-Artefakte und Maven Dependencies

WildFly JBoss Java EE 7 Specification APIs with Tools:
– jboss-javaee-7.0-with-tools
WildFly JBoss Java EE 7 Specification APIs with Resteasy:
– jboss-javaee-7.0-with-resteasy
WildFly JBoss Java EE 7 Specification APIs with Hibernate:
– jboss-javaee-7.0-with-hibernate

Weiterhin werden die folgenden JEE Dependencies (für das Servlet API, Annotationen, JAX-RS Implementierungen, JBoss RESTEasy, Jackson, Hibernate, JPA und EJB) verwendet:

– jboss-annotations-api_1.1_spec
– jboss-jaxrs-api_2.0_spec
– resteasy-jackson2-provider

– hibernate-jpa-2.1-api
– jboss-ejb-api_3.2_spec
– hibernate-jpamodelgen
– jboss-servlet-api_3.1_spec

Und ebenfalls die CDI 1.1 Dependency:

– cdi-api_1.1

Dabei erfolgt die Aktivierung von CDI mittels beans.xml im WEB-INF Verzeichnis.

über die Architektur und die verwendeten Design Patterns der Beispiel-Applikationen gibt es bereits Informationen in diesem Blog-Eintrag hier und bereits vorausgegangenen Blog-Einträgen.

Einsatz von Primefaces

Die Einbindung der erforderlichen Primefaces-UI-Bibliothek primefaces-6.0.jar erfolgt ganz simpel über die entsprechende Maven Primefaces Dependency in der pom.xml. Es ist also kein extra /lib-Verzeichnis und keine build.xml für einen Ant Build-Prozess erforderlich, denn es wird einfach der folgende Eintrag zur pom.xml für den Maven Build hinzugefügt:

<dependency>
      <groupId>org.primefaces</groupId>
      <artifactId>primefaces</artifactId>
      <version>6.0</version>
    </dependency>

Allein durch Änderung dieses Eintrags in der pom.xml kann jederzeit auch auf die gewünschte Primefaces-Version umgestellt werden. Bei der Umstellung der ca. 80 XHTML-Views von MyFaces auf Primefaces sind der Primefaces Showcase und der Primefaces Users Guide (PDF) sehr hilfreich. Der größte Aufwand der Migration besteht hierbei im Austausch der Standard MyFaces-Tags (h: Präfix) durch die Primefaces-Tags (p: Präfix) ist also für die simplen Beispiel-Applikationen leicht umsetzbar. Ebenfalls wurde das sehr gute bei DZone erhältliche PDF zur JSTL (Java Server Pages Template Library) verwendet und zwei weitere Dokumente über genauere Details zum JSF 2-Lifecycle, die sich hier und hier zum Download finden.

Aktiviert werden die Primefaces-Tags in der gewünschten XHTML-Seite mittels folgendem Eintrag im Dokumenten-Kopf der XHTML-View xmlns:p=“http://primefaces.org/ui und die zusätzliche Funktionalität der JSTL-Tags wird entsprechend, wie in den MyFaces-Views auch, per xmlns:c=“http://java.sun.com/jsp/jstl/core verfügbar gemacht.

Durch die Verwendung von CDI 1.1 haben die JSF ManagedBeans stattdessen die Annotation @Named und bleiben, bis auf ein paar Helper-Methoden zur Ausgabeformatierung, nahezu identisch zu den ManagedBeans der MyFaces-Applikation bookstore.

Weitere Informationen zu JSF 2.2, CDI und dem @ViewScope gibt es auch auf stackoverflow.com. Die dort beschriebenen Themen finden sich auch in den ManagedBeans der JSF 2.2 Beispiel-Applikation wieder.

Für die Migration von RichFaces 4 Applikationen auf Primefaces gibt es in diesem Blog hier ebenfalls eine sehr nützliche Anleitung. Es wird hierzu auch noch einen Blog-Eintrag geben. Hier noch eine weitere SPA (Single Page Appliction) Beispiel-Applikation, bei der das Testen des Backends mittels Arquillian und das integrative Testen des Frontends mittels Selenium (Workflow und UX Elemente) und QUnit (Javascript-Framework zum Test-Aufruf der REST-Endpoints aus einer Browser-View) ausführlich beschrieben ist.

Weitere Informationen zu JSF 2.2, CDI und Primefaces finden sich auch hier im Blog von Balus C. Detail-Informationen zur JavaScript-Bibliothek jQuery, die vom Primefaces-Framework sehr intensiv verwendet wird, finden sich hier: jquery.org

forge.taglib.xml:

Die in den Beispiel-Applikationen verwendete, moderne Forge TagLib kann sehr einfach erweitert werden, indem die zusätzlich benötigten Methoden in der ViewUtils-Klasse ergänzt werden und deren Signaturen in der forge.taglib.xml im Verzeichnis src/main/webapp/WEB-INF/classes/META-INF/ bekanntgemacht werden, also genau wie bei klassischen TagLibs mit dem Unterschied, dass die verwendeten Tags innerhalb der Applikation in der ViewUtils-Klasse implementiert werden, was für die Applikation zusätzliche Sicherheit bringt. Diese Tags sind für jede Applikation sehr leicht adaptierbar und können genau auf die Applikation zugeschnitten werden. Die TagLib wird in der entsprechenden .xhtml-View über den Eintrag xmlns:forgeview=“http://jboss.org/forge/view“ mit dem Prefix forgeview unter der DOCTYPE-Definition im ui:composition eingebunden und mittels forgeview-Prefix per Expression Language (EL) an der gewünschten Stelle mit den richtigen Input-Parametern aufgerufen. Hier die forge.taglib.xml für die Beispiel-Applikation bookstore-primefaces:

<?xml version=“1.0“ encoding=“UTF-8“?>
<!DOCTYPE facelet-taglib PUBLIC “-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN“ “http://java.sun.com/dtd/facelet-taglib_1_0.dtd“>
<facelet-taglib xmlns=“http://java.sun.com/JSF/Facelet“>
<namespace>http://jboss.org/forge/view</namespace>
<function>
<function-name>asList</function-name>
<function-class>de.binaris.bookstore.view.ViewUtils</function-class>
<function-signature>
java.util.List asList(java.util.Collection)
</function-signature>
</function>

<function>
<function-name>display</function-name>
<function-class>de.binaris.bookstore.view.ViewUtils</function-class>
<function-signature>
java.lang.String display(java.lang.Object)
</function-signature>
</function>

<function>
<function-name>count</function-name>
<function-class>de.binaris.bookstore.view.ViewUtils</function-class>
<function-signature>
int count(java.util.Collection)
</function-signature>
</function>

<function>
<function-name>displayShort</function-name>
<function-class>de.binaris.bookstore.view.ViewUtils</function-class>
<function-signature>
java.lang.String displayShort(java.lang.Object, int)
</function-signature>
</function>

<function>
<function-name>displayRange</function-name>
<function-class>de.binaris.bookstore.view.ViewUtils</function-class>
<function-signature>
java.lang.String displayRange(java.lang.Object,java.lang.Object)
</function-signature>
</function>

<function>
<function-name>displayFirst</function-name>
<function-class>de.binaris.bookstore.view.ViewUtils</function-class>
<function-signature>
java.lang.String displayFirst(java.lang.Object)
</function-signature>
</function>

<function>
<function-name>listExcludingSelectedOne</function-name>
<function-class>de.binaris.bookstore.view.ViewUtils</function-class>
<function-signature>
java.util.List listExcludingSelectedOne(java.util.Collection,java.lang.Object)
</function-signature>
</function> 
</facelet-taglib>

Mit entsprechenden Implementierungen der Tag-Funktionalitäten in der ViewUtils-Klasse unter Verwendung generischer Typen T und Collections List<T>.

Durch die soeben gezeigten Beispiele ist erkennbar, wie simpel es ist, eigene Tags für die .xhtml-Views heutiger JSF 2-Applikationen zu definieren und deren Utility functions-Signaturen im WEB-INF/classes/META-INF-Verzeichnis des classpaths als *name*-taglib.xml mit dem genannten XML Document-Header und dem jboss-forge-view namespace zu deklarieren (s.o. forge.taglib.xml).

Alle XML und XHTML-Dateien der Primefaces-Beispielapplikation finden sich im Deployment-Archiv bookstore-primefaces.war im /target-Unterverzeichnissen des Projekts bookstore-primefaces.

WildFly Anbindung an MySQL5, Postgres 9 und deklarative WildFly 11 Hibernate-Konfiguration

Die Konfiguration des JBoss WildFly Application Servers 11 Final erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2, 9 und 10 Final und betrifft die Datasource, die MySQL-Datenbank Inno DB 5.x, Hibernate 5, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle ein wichtiges Thema, welches noch genauer beschrieben werden wird. Die Anbindung an die relationale Datenbank MySQL 5 erfolgt übrigens analog für die JBoss Application Server WildFly 8.1, 8.2, 9, 10 und WildFly 11.

Je nach verwendeter Datenbank kann in der persistence.xml im Deployment-Paket der Beispiel-App bookstore-primefaces ein entsprechender Dialekt eingetragen werden:

Hier die /META-INF/persistence.xml der Beispiel-Applikation für MySQL5:

<xml version=“1.0″ encoding=“UTF-8″?>
    <persistence version=“2.0″ xmlns=“http://java.sun.com/xml/ns/persistence“  xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
    xsi:schemaLocation=“http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd“>
    <persistence-unit name=“BookstorePU“>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>
            java:jboss/datasources/BookstoreDatasource
    </jta-data-source>
    <properties>
    <property name=“hibernate.hbm2ddl.auto“ value=“none“/>
    <property name=“hibernate.show_sql“ value=“false“/>
    </properties>
    </persistence-unit>
    </persistence>

Dafür wird je Datenbank die folgende Datasource benötigt und ist in der standalone/configuration/standalone.xml des JBoss WildFly Servers unter den <datasources> einzutragen:

Für MySQL 5:

    <datasource jndi-name=“java:jboss/datasources/BookstoreDatasource“ pool-name=“BookstoreDS“
    enabled=“true“>
    <connection-url>jdbc:mysql://localhost:3306/bookstore</connection-url>
    <driver>mysql-connector-java-5.1.34.jar</driver>
    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
    <pool>
    <min-pool-size>10</min-pool-size>
    <max-pool-size>100</max-pool-size>
    <prefill>true</prefill>
    </pool>
    <security>
    <user-name>root</user-name>
    <password>das entsprechende Passwort</password>
    </security>
    <statement>
    <prepared-statement-cache-size>32</prepared-statement-cache-size>
    <share-prepared-statements>true</share-prepared-statements>
    </statement>
    </datasource>

Für Postgres 9:

    <datasource jndi-name=“java:jboss/datasources/BookstoreDatasource“ pool-name=“BookstoreDS“ enabled=“true“>
    <connection-url>jdbc:postgresql://localhost:5432/bookstore</connection-url>
    <driver>postgresql-9.4.1209.jar</driver>
    <transaction-isolation>TRANSACTION_READ_COMMITTED
    </transaction-isolation>
    <pool>
    <min-pool-size>10</min-pool-size>
    <max-pool-size>100</max-pool-size>
    <prefill>true</prefill>
    </pool>
    <security>
    <user-name>root</user-name>
    <password>[das entsprechende Password]</password>
    </security>
    <statement>
    <prepared-statement-cache-size>32</prepared-statement-cache-size>
    <share-prepared-statements>true</share-prepared-statements>
    </statement>
    </datasource>

Für die erfolgreiche Anbindung der soeben deklarierten Datasoures werden die Datenbank-Treiber auf Modul-Ebene des JBoss WildFly konfiguriert, wie hier für den MySQL JDBC4 Treiber beispielhaft auf dem WildFly 8.2 beschrieben wurde.

Damit die Datasources die soeben konfigurierten Treiber auch finden, werden diese in der /standalone/configuration/standalone.xml bei den <datasources> deklariert:

Für Postgres 9:

<driver name=“postgresql-java-9.4.1209.jar“ module=“org.postgresql“>
   <driver-class>org.postgresql.Driver</driver-class>
   <xa-datasource-class>org.postgresql.xa.PGXADataSource
   </xa-datasource-class>
</driver>

Für MySQL 5:

<driver name=“mysql-connector-java-5.1.34.jar“ module=“com.mysql“>
   <driver-class>com.mysql.jdbc.Driver</driver-class>
   <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
   </xa-datasource-class>
</driver>

Hier auch der komplette MySQL-Export der Beispiel-Applikation bookstore-primefaces:

Für MySQL 5: export_bookstore_database.sql

Die Hibernate-Konfiguration des WildFly 11 Final Servers ist ebenfalls leicht durchführbar. Hierfür werden im WildFly11 Server-Verzeichnis wildfly-11.0.0.Final/modules/system/layers/base/org/hibernate/main folgende Dateien hinterlegt:

– hibernate-core-5.1.10.Final.jar
– hibernate-entitymanager-5.1.10.Final.jar
– hibernate-envers-5.1.10.Final.jar
– hibernate-java8-5.1.10.Final.jar
– jipijapa-hibernate5-11.0.0.Final.jar
– module.xml
– mysql-connector-java-5.1.34.jar
– mysql-connector-java-5.1.34.jar.index

Die fertige Beispiel-Applikation bookstore-primefaces kann zusammen mit den anderen Beispiel-Applikationen hier betrachtet werden (MySQL5 Server, Postgres 9 auf Linux).

Hier der WildFly 10 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8.

Die fertig konfigurierte Version des WildFly 10.Final mit vielen Beispiel-Applikationen der vorigen Blog-Einträge hier zum Download bereit kann runtergeladen, entpackt und gestartet werden. Dabei ist nur der Pfad für JAVA_HOME in der standalone.xml anzupassen, wie in diesem Blog-Eintrag hier beschrieben wurde, damit dieser auf das tatsächliche JDK 8-Verzeichnis des Server-Systems zeigt und auch der Pfad für das log-Dateien Verzeichnis in der Datei [server]/standalone/configuration/logging.properties.

Hier auch der WildFly 11 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Minimale Voraussetzung ist jeweils Java 8, er wird hier aber bereits mit Java 9 betrieben. Der fertig konfigurierte WildFly 11 mit vielen weiteren Beispiel-Applikationen ist hier zum Download verfügbar, kann runtergeladen, entpackt und gestartet werden.

Auch hier ist nur der Pfad des JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 9 – Verzeichnis des Server-Systems zeigt und ebenfalls der Pfad für das log-Dateien Verzeichnis in der logging.properties.

Mehr Informationen zum neulich erschienenen Java 9 Release gibt es hier:

https://www.technotification.com/2017/09/java-9-is-finally-released.html

Herunterladen kann man sich das neue Java 9 für die gewünschte Betriebssystem-Plattform hier:

http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html

In Fällen mit Migrations-Bedarf gibt es hier weitere Informationen.

Hier die Release-Notes zu Java 9:

http://www.oracle.com/technetwork/java/javase/9-relnotes-3622618.html

Hier auch nochmal die ausführliche Dokumentation einer weiteren JEE Beispielapplikation mit Selenium-Tests und Javascript QUnit-Tests.

Hier das Beispiel-Projekte für die Eclipse-Entwicklungsumgebung JBoss Developer Studio: bookstore-primefaces

Die Primefaces Beispiel-Applikation dieses Blog-Eintrags kann danach selbst erneut deployt werden, ohne den bereits gestarteten WildFly 11 Application Server überhaupt stoppen oder erneut starten zu müssen. Bei laufendem Server einfach ins Server-Unterverzeichnis /standalone/deployments

– wenn das Deployment des bookstore-primefaces.war Archivs nicht unverzüglich startet, eine leere Textdatei namens bookstore-primefaces.war.dodeploy speichen und
sofort wird die Beispiel-Applikation deployt und in wenigen Sekunden gestartet und kann aufgerufen werden:

http://[domainname z. B. localhost]:[http-port, z. B. 8080]/bookstore-primefaces

Fazit: Wie man sieht, macht es einfach viel Freude, z.B. mittels JBoss Forge und JPA 2 Entities robuste, komfortable, Browser-basierte Primefaces 6-Fontends oder eben die responsiven Angular JS Apps auf dem Datenmodell zu erzeugen und weiterzuentwickeln und diese an einen neuen, die JEE7-Spezifikation erfüllenden JBoss WildFly (WildFly 9, WildFly 10 und 11) anzubinden. Die Blog-Einträge dazu können hier nach Stichworten und Erscheinungsmonat leicht durchsucht werden.

Somit besteht durchaus die Möglichkeit, dass noch weitere Blog-Einträge zu Webframeworks wie Primefaces 6, Angular JS und Bootstrap, sowie den die JEE7-Spezifikation implementierenden WebService-und Backend-Technologien folgen. Allen interessierten Leserinnen und Lesern weiterhin viel Freude bei der agilen Softwareentwicklung mittels Scrum und dem Test-Driven Development mit Java, sowie weiterhin schöne Sommerferien.

Services – mit REST, JPA 2, EJB 3.2, JEE7, WildFly, Forge

 Die Motivation

Das MVC Framework ‘Angular JS‘ ermöglicht ebenfalls unter Einsatz des Router Design Patterns und des Front Controller Design Patterns das Erstellen von responsiven (Mobile) Applikationen zur Stammdatenpflege von über ein Service Interface verfügbaren Daten aus einem RESTful WebService. Die erstellte JEE7 Beispiel-Applikation ‘bookstore-angularjs‘ arbeitet auf Basis der Template-Technologie und ermöglicht die leichte Pflege von und die Suche nach Produkten, z. B. Bücher, bestimmter Kategorien, z. B. Belletristik, und Bestellungen von Kunden etc. Die Beispiel-Applikation verwendet JPA-Entities, außerdem werden mittels JBoss Forge sowohl JSF 2.2 Benutzerschnittstellen verfügbar gemacht, als auch die Angular JS GUIs. An diesem einfachen, übersichtlichen JEE7 Beispielprojekt wird dadurch die Verwendung der eingesetzten Technologien gezeigt und dieses als .war Archiv-Deployment auf dem JBoss WildFly 8.2 Application Server und weiteren Application Servern zum Test zur Verfügung gestellt. Hier das Entity-Relationship Diagramm (“E-R-Diagramm“) der ‘bookstore‘ MySQL-Datenbank:

E-R-diagram
(E-R-Diagramm der Beispiel-Applikation ‘bookstore-angularjs’)

TDD der Beispiel Applikation

Wie zusätzliche Selenium-Tests mit dem Selenium FireFox-PlugIn durchgeführt und diese Tests gespeichert werden können, wurde bereits in einem Blog-Eintrag in diesem Blog beschrieben. Diese Selenium Tests können gespeichert und in einer Test-Suite zusammengefasst werden, um auch später jederzeit die korrekte Funktionsweise der Eingabe-Aktionen und Link-Aufrufe der responsiven Applikation automatisiert verifizieren zu können.

Die Technologien:

Die Beispiel-Applikation ‘bookstore-angularjs‘ verwendet im Frontend Angular.js und HTML5-/CSS3, als auch die JavaScript-Bibliotheken Bootstrap.js, Backbone.js, jQuery und jQuery Mobile, sowie die Underscore.js Tools.

Für das JAX-RS Service-Backend kommt Java EE zum Einsatz (Stateful/Stateless EJB 3.2 und JEE 7) und im Backend Model JPA 2.1 Entities. Die Applikation wurde auf dem ‘JBoss WildFly 8.2‘ und dem ‘JBoss EAP 6.3‘ Applikationsserver, sowie weiteren Applikationsservern erfolgreich deployt und getestet und kann gerne weiterverwendet und als Open Source weiterentwickelt werden.

Für die Weiterentwicklung, den Build und das Deployment des Projekts ist mindestens Java 6 und Maven 2 erforderlich. Als Entwicklungsumgebung wurde Eclipse in Form des “JBoss Developer Studios“ mit Java 7 und Java 8 verwendet und die FireFox WebDeveloper IDE/Tools.

Wie für die Applikation ‘bookstore-angularjs‘ in der pom.xml des Beispielprojekts nach erfolgtem Download erkennbar ist, werden auch hier die folgenden JEE 7 Artefakte für den JBoss WildFly verwendet und importiert:

WildFly JBoss Java EE 7 Specification APIs with Tools:
– jboss-javaee-7.0-with-tools
WildFly JBoss Java EE 7 Specification APIs with Resteasy:
– jboss-javaee-7.0-with-resteasy
WildFly JBoss Java EE 7 Specification APIs with Hibernate:
– jboss-javaee-7.0-with-hibernate

Weiterhin werden die folgenden JEE Dependencies (für das Servlet API, Annotationen, JAX-RS Implementierungen, JBoss RESTEasy, Jackson, Hibernate, JPA und EJB) verwendet:

– jboss-annotations-api_1.1_spec
– jboss-jaxrs-api_2.0_spec
– resteasy-jackson2-provider

– hibernate-jpa-2.1-api
– jboss-ejb-api_3.2_spec
– hibernate-jpamodelgen
– jboss-servlet-api_3.1_spec

Einsatz von CDI

Und ebenfalls die CDI 1.1 Dependency:

– cdi-api_1.1

Die Aktivierung von CDI erfolgt mittels beans.xml im WEB-INF Verzeichnis.

Die Architektur

a) Das Service Backend:

Die Beispiel-Applikation verwendet die folgenden Entities, die hier gelistet sind:

– Address
– Country
– Category
– Customer
– Product
– Item
– OrderLine
– PurchaseOrder
– CreditCard
– CreditCardType

Die Relationen und Constraints (HibernateValidation) zeigen sich auch in den entsprechenden JPA 2.1 Entities und deren Annotationen.

b) Der RESTful WebService mit den Service-Endpoints:

Soweit die beschriebenen Entities der Beispiel-Applikation ‘bookstore-angularjs‘. Hieraus lassen sich mit dem JBoss Developer Studio und dem JBoss Forge PlugIn über das Kontextmenü auf dem Maven-Projekt der RESTful WebService mit den Service-Endpoints generieren.

Die RESTful WebService-Endpoints verwenden wiederum die folgenden DTOs.

– AddressDTO
– CategoryDTO
– CountryDTO
– CreditCardDTO
– CustomerDTO
– ItemDTO
– NestedCategoryDTO
– NestedCountryDTO
– NestedCustomerDTO
– NestedItemDTO
– NestedOrderLineDTO
– NestedProductDTO
– NestedPurchaseOrderDTO
– OrderLineDTO
– ProductDTO
– PurchaseOrderDTO

Nun könnten auf dem Maven-Projekt mittels Forge/Scaffold die gewünschten View-Beans für eine JSF-Beispiel-Applikation generiert werden. Die Architektur und die Assoziationen für die Auswahl des Angular JS MVC Frameworks wurden bereits im Beispiel-Projekt ‘educationorganizer‘ eingehend erläutert und können dort nachgelesen werden. Für JSF 2.2 Views (Auswahl JSF) wüde man die folgenden BackingBeans mit den entsprechenden CDI Annotationen (@Named anstatt @ManagedBean, etc.) erhalten:

– CategoryBean
– CountryBean
– CustomerBean
– ItemBean
– LocaleBean
– OrderLineBean
– ProductBean
– PurchaseOrderBean

Die Konfiguration des JBoss WildFly Application Servers kann hier nachgelesen werden.

Diese Minimal-Konfiguration betrifft:

– die MySQL Datenbank/den Java MySQL-Datenbank-Treiber und die MySQL-Datasource der
‘bookstore-angularjs‘ Beispiel-Applikation
– die Hibernate Version und ihre interessierenden Features/Dependencies
– das Start-Skript des WildFly Application Servers

Eine fertige Version mit Beispiel-Konfiguration der Beispiel-Applikation ‘bookstore-angulars‘ kann aus dem /target-Unterverzeichnis des heruntergeladenen Beispielprojekts hier, in ein beliebiges Verzeichnis ausgepackt und durch Starten von standalone.bat (Windows) oder standalone.sh (Linux) sofort gestartet werden. Anschließend ist die Beispiel-Applikation aufrufbar unter der folgenden Url:

http://localhost:8080/bookstore-angularjs/app.html#/ oder hier bei den JEE-Beispiel-Applikationen.

Die Test-Frameworks und die Tests

a) Arquillian Tests für das Service-Backend

wurden in einem Blog-Eintrag in diesem Blog bereits erklärt.

b) QUnit-Tests für die REST-Services

wurden in einem Blog-Eintrag in diesem Blog bereits erklärt.

c) Selenium Tests für die Benutzerschnittstelle

wurden in einem Blog-Eintrag in diesem Blog bereits erklärt.

Bei dieser Gelegenheit darf auch das sehr effektive, interessante und erfolgreiche Seminar

TDD mit Java”

von Binaris Informatik erwähnt werden.

Wie Test-Suites, die mit dem Selenium IDE PlugIn durchgeführt wurden und automatisiert ausgeführt werden können, erstellt werden, wurde bereits in einem Blog Eintrag in diesem Blog beschrieben.

Hier das ‘bookstore-angularjs‘ Eclipse-Projekt zum Download:

https://github.com/UweKrull/repository/raw/master/bookstore-angularjs.zip

Hier das SQL-Skript zum Anlegen der MySQL-Datenbank zum Download:

http://educationorganizer.de/mysql_export_bookstore_database_sql.txt

Hier der WildFly 8.2 als Zip-Archiv zum Download und Entpacken:

http://download.jboss.org/wildfly/8.2.0.Final/wildfly-8.2.0.Final.zip

Installation/Start der Beispiel-Applikation:

– Die MySQL-Datenbank per SQL-Skript anlegen.

– JAVA_HOME, JBOSS_HOME entsprechend setzen und

in der standalone.bat oder standalone.sh verwenden und nur noch die folgende datasource in der standalone/configuration/standalone.xml eintragen:

<datasource jndi-name=“java:jboss/datasources/BookstoreDatasource“ pool-name=“BookstoreDS“ 
        enabled=“true“>
        <connection-url>jdbc:mysql://localhost:3306/bookstore</connection-url>
        <driver>mysql-connector-java-5.1.34.jar</driver>
        <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
        <pool>
                <min-pool-size>10</min-pool-size>
                <max-pool-size>100</max-pool-size>
                <prefill>true</prefill>
        </pool>
        <security>
                <user-name>root</user-name>
                <password>das entsprechende Passwort</password>
        </security>
        <statement>
                <prepared-statement-cache-size>32</prepared-statement-cache-size>
                <share-prepared-statements>true</share-prepared-statements>
        </statement>
</datasource>

– bookstore-angularjs.war ins Server-Unterverzeichnis /standalone/deployments speichern

– Neben bookstore-angularjs.war eine leere Textdatei namens bookstore-angularjs.war.dodeploy speichen.

– Server starten per standalone.bat oder standalone.sh, http://localhost:8080/bookstore-angularjs/ aufrufen

– Die Selenium Tests per Selenium IDE PlugIn/Recorder erstellen und ausführen.

Die fertig konfigurierte Version des WildFly 10.Final mit vielen Beispiel-Applikationen der vorigen Blog-Einträge hier zum Download bereit kann heruntergeladen, entpackt und gestartet werden. Dabei ist nur der Pfad für JAVA_HOME in der standalone.xml anzupassen, damit dieser auf das tatsächliche JDK 8-Verzeichnis des Server-Systems zeigt.

Allen interessierten Leserinnen und Lesern weiterhin viel Freude bei der agilen Softwareentwicklung mittels  Scrum und dem Test Driven Development mit Java, sowie schöne Sommerferien und einen erholsamen Urlaub.

Services – mit REST, JPA 2, EJB 3.2, JSF 2.2, Angular JS, Bootstrap, JBoss Forge

Die Beispiel-Applikation

Die JEE 7 Beispiel-Applikation ‘library‘ arbeitet mit JSF 2.2 auf Basis der Template-Technologie und ermöglicht die leichte Pflege von und die Suche nach Buchausleihen oder Ausleihen anderer Medien, z.B. PDFs, bestimmter Kategorien durch Kunden einer Stadtbücherei (Stammdatenpflege und Bestandsdatenpflege). Die Beispiel-Applikation verwendet im Backend JPA 2 – Entities und  EJB 3.2.

Mittels JBoss Forge werden sowohl JSF 2.2 Benutzerschnittstellen verfügbar gemacht, als auch die Angular JS GUIs der zweiten JEE 7 Beispiel-Applikation ‘library-angularjs‘. Mit dieser zweiten, responsiven Applikation kann  sich der Kunde der Stadtbücherei auch unterwegs im Browser auf seinem Smartphone die Bibliotheksausleihen ansehen und verwalten, oder nach interessanten Büchern stöbern. Durch diese zwei simplen, übersichtlichen JEE7 Beispielprojekten wird die Verwendung und Effektivität der eingesetzten Technologien gezeigt und diese jeweils als .war Archiv-Deployment auf dem JBoss WildFly 10 Application Server zum Test zur Verfügung gestellt. Hier das Entity-Relationship-Diagramm der ‘library’ Datenbank:

E-R-diagram
(E-R-Diagramm der Beispiel-Applikationen ‘library’ und ‘library-angularjs’)

TDD der Beispiel Applikationen

Wie zusätzliche Selenium-Tests mit dem Selenium FireFox-PlugIn durchgeführt und diese Tests gespeichert  werden können, ist bereits in diesem Blog-Eintrag hier beschrieben. Diese Selenium Tests können gespeichert und in einer Test-Suite zusammengefasst werden, um auch später jederzeit die korrekte Funktionsweise der Eingabe-Aktionen und Link-Aufrufe der Mobile Applikation automatisiert verifizieren zu können.

Bei dieser Gelegenheit darf auch das sehr effektive, interessante und erfolgreiche Seminar

“TDD mit Java”

von Binaris Informatik ebenfalls erwähnt werden.

Verwendete Technologien

a) Die Beispiel-Applikation ‘library-angularjs’:

Die Beispiel-Applikation ‘library-angularjs‘ verwendet im Frontend Angular.js und HTML5-/CSS3, als auch die JavaScript-Bibliotheken Bootstrap.js und in sehr geringem Maß jQuery.

Das MVC Framework ‘Angular JS‘ ermöglicht bekanntlich unter Einsatz des Router Design Patterns und des Front Controller Design Patterns das Erstellen von responsiven (Mobile) Applikationen zur über ein Service Interface verfügbaren Daten aus einem RESTful WebService.

In AngularJS werden mit HTML-Code deklarativ die Oberflächen gestaltet. Ein weiterer Aspekt dabei ist, dass Anwendungslogik nur in den JavaScript-Dateien definiert wird. Dieser sollte weitmöglichst unabhängig von der Benutzeroberfläche bzw. der Anwender-Schnittstelle (User interface) sein. Im Gegensatz zu anderen MVC-Frameworks erweitert AngularJS den HTML-Code, anstatt diesen komplett zu kapseln.

Um einen Bereich einer HTML-Seite von AngularJS verwalten zu lassen, muss dieser von einem Element mit dem Attribut ‘ng-app’ umschlossen sein. Nach dem Laden der Seite sucht AngularJS nach dem Atrribut ‘ng-app’ und analysiert den davon umschlossenen Bereich. ‘Controller’ werden in AngularJS mit dem Attribut ‘ng-controller’ definiert. Controller und View kommunizieren über den ‘Scope’, einen Container auf dessen Inhalt von beiden Seiten aus zugegriffen werden kann. Mit der ‘{{}}’ Notation kann mittels einem One-Way-Binding im HTML auf Elemente des ‘Scope’ zugegriffen werden. Die Daten können angezeigt, aber nicht zurückgeschrieben werden. Two-Way-Bindings ermöglichen auch das Schreiben in den ‘Scope’ und können logischerweise nur an HTML-Input-Elementen verwendet werden.

Eine Iteration über alle Elemente einer list kann in AngularJS mit der Anweisung ‘ng-repeat’ erfolgen, wie im Beispiel ‘library-angularjs‘ zu sehen ist. Innerhalb jedes ‘<li>‘ Elementes wird dann z. B. der Inhalt der Property ‘text’ jedes Listenelementes ausgegeben, welches in der Beispiel-Applikation für das jeweilige Edit-Template innerhalb des jeweilgen JavaScript edit*Controllers an die Erfordernisse angepasst werden kann und für das jeweilige Search-Template innerhalb der jeweiligen search.html.

b) Die Beispiel-Applikation ‘library‘:

Die Beispiel-Applikation ‘library‘ verwendet im Frontend JSF 2.2 und .xhtml-Templates mit HTML5-/CSS3. Hier können auch leicht Rich Faces oder Primefaces, also die jeweils gewünschte JSF-Implementierung anstatt dem MyFaces-Default zum Einsatz kommen. Zusätzlich wird die Forge TagLib verwendet (siehe /META-INF/forge.taglib.xml), welche eine modernere Version einer TagLib ist.

Über den klassischen Einsatz von Tags und TagLibs, z.B. im Zusammenhang mit dem Struts Framework, gibt es bereits einen Blog-Eintrag und oder im Zusammenhang mit Spring Roo einen weiteren Blog-Eintrag in diesem Blog.

c) Das RESTful WebService-Backend beider Beispiel-Applikationen:

Für das JAX-RS Service-Backend beider Beispiel-Applikationen kommt Java EE zum Einsatz (Stateful/Stateless EJB 3.2 und JEE 7) und im Backend Model JPA 2.1 Entities. Über ein Service Interface werden die interessierenden Daten der Beispiel-Applikationen aus einem RESTful WebService verfügbar gemacht.

Maven JEE 7 Artefakte und Dependencies

Wie die Applikationen ‘library‘ und ‘library-angularjs‘ mittels JBoss Forge erstellt werden, ist in diesem Blog-Eintrag hier bereits beschrieben worden, und wie in der pom.xml des jeweiligen Beispielprojekts nach erfolgtem  Download erkennbar ist, werden auch hier die folgenden JEE 7 Artefakte für den JBoss WildFly verwendet und  importiert:

WildFly JBoss Java EE 7 Specification APIs with Tools:
– jboss-javaee-7.0-with-tools
WildFly JBoss Java EE 7 Specification APIs with Resteasy:
– jboss-javaee-7.0-with-resteasy
WildFly JBoss Java EE 7 Specification APIs with Hibernate:
– jboss-javaee-7.0-with-hibernate

Weiterhin werden die folgenden JEE Dependencies (für das Servlet API, Annotationen, JAX-RS Implementierungen, JBoss RESTEasy, Jackson, Hibernate, JPA und EJB) verwendet:

– jboss-annotations-api_1.1_spec
– jboss-jaxrs-api_2.0_spec
– resteasy-jackson2-provider

– hibernate-jpa-2.1-api
– jboss-ejb-api_3.2_spec
– hibernate-jpamodelgen
– jboss-servlet-api_3.1_spec

Einsatz von CDI

Und ebenfalls die CDI 1.1 Dependency:

– cdi-api_1.1

Die Aktivierung von CDI erfolgt mittels beans.xml im WEB-INF Verzeichnis.

Deployment auf JBoss WildFly und Konfigurationen

Die Beispiel-Applikationen wurden auf dem ‘JBoss WildFly 8.2‘ und dem ‘JBoss EAP 6.3‘, sowie dem ‚WildFly 10‘ und dem ‚JBoss EAP 7.0‘ Applikationsserver erfolgreich deployt und getestet und können gerne weiterverwendet und als Open Source weiterentwickelt werden.

Für die Weiterentwicklung, den Build und das Deployment des Projekts ist mindestens Java 7 und Maven 3 erforderlich. Als  Entwicklungsumgebung wurde Eclipse in Form des “JBoss Developer Studios“ mit Java 7 und Java 8 verwendet und die FireFox WebDeveloper IDE/Tools. Als Datenbank wurde MySQL InnoDB 5.x eingesetzt, hier kann aber auch leicht PostgreSQL oder auch gerne eine andere Open Source-Datenbank verwendet werden.

Die Konfiguration des JBoss WildFly Application Servers 10 Final erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2 und 9 Final und betrifft die Datasource, die MySQL-Datenbank Inno DB 5.x, Hibernate 5, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle, in Blog-Einträgen dieses Blogs bereits beschrieben.

Diese Minimal-Konfiguration betrifft:

  • die MySQL Datenbank/den Java MySQL-Datenbank-Treiber und die MySQL-Datasource der
  • ‘library‘ Beispiel-Applikation
  • die Hibernate Version und ihre interessierenden Features/Dependencies
  • das Start-Skript des WildFly Application Servers

Eine fertige Version der Beispiel-Applikation ‘library‘ kann heruntergeladen und ins Verzeichnis /standalone/deployments gespeichert werden. Genauso kann mit der Beispiel-Applikation ‘library-angularjs‘ verfahren werden. Durch Starten von standalone.bat (Windows)  oder standalone.sh (Linux) kann der JBoss WildFly gestartet werden.

Und die Beispiel-Applikation ‘library-angularjs‘ ist danach z. B. aufrufbar unter der Url: http://localhost:8080/library-angularjs

Die Test-Frameworks und die Tests

a) Arquillian Tests für das Service-Backend

b) QUnit-Tests für die REST-Services

c) Selenium Tests für die Benutzerschnittstelle

Wie Test-Suites, die mit dem Selenium IDE PlugIn durchgeführt wurden und automatisiert ausgeführt werden können, erstellt werden, wurde bereits in diesem Blog beschrieben.

Hier nun auch das Beispiel-Projekt library.zip zum Download und hier ebenfalls das Beispiel-Projekt library-angularjs.zip, in welchem mittels JBoss Forge PlugIn die ausgewählten JSF 2.2 oder Angular JS Views und der RESTful WebService generiert wurden.

Hier das SQL-Skript library.sql zum Anlegen der MySQL-Datenbank zum Download:

library.sql

Hier der WildFly 8.2 als Zip-Archiv zum Download und Entpacken:

wildfly-8.2.0.Final

Und hier auch der WildFly 10 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank für den WildFly 9 und den WildFly 10 gibt es bereits mehr Informationen in diesem Blog.

Die fertig konfigurierte Version des WildFly 10.Final mit vielen Beispiel-Applikationen der vorigen Blog-Einträge hier zum Download bereit kann runtergeladen, entpackt und gestartet werden. Dabei ist nur der Pfad für JAVA_HOME in der standalone.xml anzupassen, damit dieser auf das tatsächliche JDK 8-Verzeichnis des Server-Systems zeigt.

Installation/Start der Beispiel-Applikation:

– Die MySQL-Datenbank per library.sql-Skript anlegen.

– JAVA_HOME, JBOSS_HOME entsprechend setzen und

in der standalone.bat oder standalone.sh verwenden oder den vorkonfigurierten Server auspacken Dann noch die folgende datasource (dieselbe für beide Beispiel-Projekte) in der standalone/configuration/standalone.xml eintragen

<datasource jndi-name=“java:jboss/datasources/LibraryDatasource“ pool-name=“LibraryDS“
        enabled=“true“>
        <connection-url>jdbc:mysql://localhost:3306/library</connection-url>
        <driver>mysql-connector-java-5.1.34.jar</driver>
        <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
        <pool>
                <min-pool-size>10</min-pool-size>
                <max-pool-size>100</max-pool-size>
                <prefill>true</prefill>
        </pool>
        <security>
                <user-name>root</user-name>
                <password>das entsprechende Passwort</password>
        </security>
        <statement>
                <prepared-statement-cache-size>32</prepared-statement-cache-size>
                <share-prepared-statements>true</share-prepared-statements>
        </statement>
</datasource>

library.war ins Server-Unterverzeichnis /standalone/deployments speichern
library-angularjs.war ins Server-Unterverzeichnis /standalone/deployments speichern
– Server starten per standalone.bat oder standalone.sh,
http://localhost:8080/library/ bzw. http://localhost:8080/library-angularjs/ aufrufen

– Die Selenium Tests per Selenium IDE PlugIn/Recorder erstellen und ausführen.

Allen interessierten Leserinnen und Lesern weiterhin viel Freude bei der agilen Softwareentwicklung mittels  Scrum und dem Test Driven Development mit Java, sowie weiterhin eine schöne Sommerzeit.

WebApps – mit JSF 2, RichFaces 4, Primefaces 6, REST, JPA 2, EJB 3, JEE7, JBoss WildFly

Die Motivation

Über die Migration von JBoss RichFaces Beispiel-Applikationen auf die sehr vorteilhafte Primefaces 6-Technologie gibt es bereits Blog-Einträge in diesem Blog hier. In diesem Blog-Eintrag soll nun passend zum Datenmodell des vorigen Blog-Eintrags mit der Angular JS Beispiel-Applikation restaurantguide-angularjs eine Primefaces 6 Beispiel-Webapplikation restaurantguide-primefaces erstellt werden. Hier nochmal das Entity-Relationship-Diagramm:

E-R-diagram
(Anm.: Die Tabelle registered_customer stellt den Restaurantkritiker („Critic“) dar.)

Dabei werden als Basis-Frontendtechnologien JSF 2 und Primefaces 6 verwendet. Weiterhin wird der Einsatz moderner Tag-Libs in den XHTML-Seiten der JEE7-Applikation erklärt.

Über die JSF Technologie gibt es bereits einen Blog-Eintrag in diesem Blog. Die in diesem Blog-Eintrag hier mittels JBoss Forge Eclipse PlugIn erstellte Applikation restaurantguide-angularjs wurde auf dem Datenmodell mit den JPA 2 Entities erstellt, und es wird eine weitere Primefaces 6 Beispiel-Applikation restaurantguide-primefaces entwickelt, unter Einsatz von JSF 2 und der robusten, elegant gestylten, etablierten, optimalen Primefaces Frontend-Technologie.

Die Beispiel-Applikation restaurantguide-primefaces wird dann auf den JBoss WildFly 9 Final und JBoss WildFly 10 Final Application Servern deployt und kann hier getestet werden. Die Verwendung der JBoss WildFly JEE7-Application Server wurde in diesem Blog bereits beschrieben. Dabei liefern die JEE6- und JEE7-Beispielapplikationen hier mit Hilfe eines EJB 3-getriebenen Backends (Session Beans als DAOs, „DAO“-Pattern) unter Anbindung der JPA 2 Entities („Table-Per-Class“-Pattern) mit Hilfe von DTOs über fachliche RESTful ServiceInterfaces die benötigten Daten zur Präsentation und Bearbeitung (Änderung, Löschen, Neuanlage) in den Web-Frontends, welche die WebServices konsumieren („ServiceConsumer“-Pattern). Der JPA-Provider ist dabei Hibernate von JBoss, welches auf dem WildFly zu konfigurieren ist.

Erstellung der Beispiel Applikation aus dem Datenmodell

Wie in der pom.xml des jeweiligen Beispielprojekts nach erfolgtem Download erkennbar ist, wurden auch in den Applikationen restaurantguide-primefaces und restaurantguide-angularjs die folgenden JEE 7 Artefakte für den JBoss WildFly identifiziert, verwendet und importiert:

Maven JEE 7 JBoss-Artefakte und Maven Dependencies

WildFly JBoss Java EE 7 Specification APIs with Tools:
– jboss-javaee-7.0-with-tools
WildFly JBoss Java EE 7 Specification APIs with Resteasy:
– jboss-javaee-7.0-with-resteasy
WildFly JBoss Java EE 7 Specification APIs with Hibernate:
– jboss-javaee-7.0-with-hibernate

Weiterhin werden die folgenden JEE Dependencies (für das Servlet API, Annotationen, JAX-RS Implementierungen, JBoss RESTEasy, Jackson, Hibernate, JPA und EJB) verwendet:

– jboss-annotations-api_1.1_spec
– jboss-jaxrs-api_2.0_spec
– resteasy-jackson2-provider

– hibernate-jpa-2.1-api
– jboss-ejb-api_3.2_spec
– hibernate-jpamodelgen
– jboss-servlet-api_3.1_spec

Und ebenfalls die CDI 1.1 Dependency:

– cdi-api_1.1

Einsatz von CDI

Über CDI und JavaEE gibt es bereits Blog-Einträge in diesem Blog. Die Aktivierung von CDI erfolgt, wie beschrieben, mittels beans.xml im WEB-INF Verzeichnis.

Primefaces 6

Über die Architektur und die verwendeten Design Patterns der Beispiel-Applikationen gibt es bereits Informationen in einem Blog. Im Backend wird üblicherweise mit den JPA Entities begonnen. Hat man erst einmal die JPA 2.2 Entities definiert und mittels JBoss Forge die Beispiel-Webapplikationen für die ausgewählte Frontend-Technologie (Angular JS oder Faces) erzeugt und rebrandet, ist die Migration der Faces Beispiel-Applikation leicht durchführbar und wurde bereits in vorigen Blog-Einträgen beschrieben.

Die Einbindung der erforderlichen Primefaces-UI-Bibliothek primefaces-6.0.jar erfolgt dabei ganz simpel übers Hinzufügen der entsprechenden Maven Primefaces Dependency in der pom.xml.

    <dependency>
      <groupId>org.primefaces</groupId>
      <artifactId>primefaces</artifactId>
      <version>6.0</version>
    </dependency>

Allein durch Änderung dieses Eintrags in der pom.xml kann jederzeit auch auf die gewünschte Primefaces-Version umgestellt werden. Bei der Umstellung der XHTML-Views von MyFaces auf Primefaces sind der Primefaces Showcase und der neue Primefaces 6.0 Users Guide (PDF) sehr hilfreich. Der größte Aufwand der Migration besteht hierbei im Austausch der Standard MyFaces-Tags (h: Präfix) durch die Primefaces-Tags (p: Präfix) ist also für die simplen Beispiel-Applikationen leicht umsetzbar. Ebenfalls wurde das sehr gute bei DZone erhältliche PDF zur JSTL (Java Server Pages Template Library) verwendet.

Aktiviert werden die Primefaces-Tags in der gewünschten XHTML-Seite mittels folgendem Namespace Eintrag im Dokumenten-Kopf der XHTML-View xmlns:p=“http://primefaces.org/ui und die zusätzliche Funktionalität der JSTL-Tags wird entsprechend, wie in den MyFaces-Views auch, per xmlns:c=“http://java.sun.com/jsp/jstl/core verfügbar gemacht.

Durch die Verwendung von CDI 1.1 haben die JSF ManagedBeans stattdessen die Annotation @Named und bleiben ansonsten nahezu identisch zu den ManagedBeans der MyFaces-Applikationen. Weitere Informationen zu JSF 2.2, CDI und Primefaces finden sich auch hier im Blog von Balus C. Detail-Informationen zur JavaScript-Bibliothek jQuery, die vom Primefaces-Framework sehr intensiv verwendet wird, finden sich hier: jquery.org

Auf einige Details, die bei der Migration von RichFaces auf Primefaces zu berücksichtigen sind, soll kurz eingegangen werden:

Die folgenden RichFaces Dependencies sind nicht mehr erforderlich und können aus der Maven pom.xml entfernt und durch die oben angegebene Primefaces 6.0-Dependency ersetzt werden:

  <dependencyManagement>

    <dependencies>

      <dependency>

        <groupId>org.richfaces</groupId>

        <artifactId>richfaces-bom</artifactId>

        <version>4.3.5.Final</version>

        <type>pom</type>

        <scope>import</scope>

      </dependency>

    </dependencies>

  </dependencyManagement>

[…]

<!– https://mvnrepository.com/artifact/org.richfaces/richfaces –>

<dependency>

    <groupId>org.richfaces.ui</groupId>

    <artifactId>richfaces-components-ui</artifactId>

</dependency>

<dependency>

    <groupId>org.richfaces.core</groupId>

    <artifactId>richfaces-core-impl</artifactId>

</dependency>

Das Theming und Skinning der RichFaces-View in der web.xml

<context-param>

    <param-name>org.richfaces.core</param-name>

    <param-value>skin_name</param-value>

</context-param>

kann optional durch folgendes Primefaces-Theme ersetzt werden, oder ganz entfallen:

<context-param>

    <param-name>primefaces.THEME</param-name>

    <param-value>theme_name</param-value>

</context-param>

Das Entfernen aller RichFaces Namespace Definitionen aus den .xhtml-Seiten und Ersetzen durch die bereits erwähnte Primefaces Namespace Definition kann dann nach einem Update Maven Project problemlos durchgeführt werden.

Ajax Tags

Alle Ajax-verwendenden RichFaces-Komponenten nutzen Attribute zur Definition der abschließend zu rendernden Komponente und der Ausführung von Methoden innerhalb des partiellen Requests, z. B. wie der folgende Action Button, welcher nur die Felder einer bestimmten ID im Request auf den Click Event an die Backing Bean übermittelt und nur ein bestimmtes Element der .xhtml-View nach der Ausführung der genannten Action Methode rendert, wenn das execute-Attribut überschrieben wird, anstatt bei Fehlen des Attributs den execute=“@form“ Default zu verwenden.

<a4j:commandButton render=selectMenuId execute=@this

action=“#{userBean.handleChanges}“ />

In PrimeFaces, welches nicht das JSF2 Default Naming für diese zwei Attribute verwendet, wird statt render das update-Attribut verwendet und anstatt execute das process-Attribut, somit lautet der Code nach der Migration:

<p:commandButton update=”outputTextId” process=”@this”

actionListener=#{userBean.handleChanges} />

Der  p:commandButton bietet die Möglichkeit anstatt bei Fehlen des Attributs und dem Default Verhalten (ajax=”true”) stattdessen Nicht-Ajax Verhalten mittels den Attribut-Kombinationen immediate=“true“ und ajax=“false“ zu konfigurieren.

Javascript Functions in JSF Ajax Calls verwenden

Das RichFaces-Tag a4j:jsFunction, ermöglicht das Ausführen von Ajax Requests direkt von JavaScript aus, um mittels der Ajax-Requests Daten vom Server zu holen und z. B. als JSON Format in der Response zurückzugeben, um diese dann im Client-seitigen JavaScript Call weiterzuverwenden.

Dies ermöglicht den Bind einer Action oder eines Action Listeners (z.B. ValueChangeListener für den event ‚change‘) und das abschießende erneute partielle Rendering, wie bei jeder anderen Ajax-Komponente auch.

Das entsprechende PrimeFaces-Tag ist p:remoteCommand und bietet dieselbe Funktionalität, wenn auch mit anderen Attributnamen.

forge.taglib.xml

Die in den Beispiel-Applikationen verwendete, moderne Forge TagLib kann sehr einfach erweitert werden, indem die zusätzlich benötigten Methoden in der ViewUtils-Klasse ergänzt werden und deren Signaturen in der forge.taglib.xml im Verzeichnis src/main/webapp/WEB-INF/classes/META-INF/ bekanntgemacht werden, also genau wie bei klassischen TagLibs mit dem Unterschied, dass die verwendeten Tags innerhalb der Applikation in der ViewUtils-Klasse implementiert werden, was für die Applikation zusätzliche Sicherheit bringt. Diese Tags sind für jede Applikation sehr leicht adaptierbar und können genau auf die Applikation zugeschnitten werden. Die TagLib wird in der entsprechenden .xhtml-View über den Eintrag xmlns:forgeview=“http://jboss.org/forge/view“ mit dem Prefix forgeview unter der DOCTYPE-Definition im ui:composition eingebunden und mittels forgeview-Prefix per Expression Language (EL) an der gewünschten Stelle mit den richtigen Input-Parametern aufgerufen. Hier die forge.taglib.xml für die Beispiel-Applikation restaurantguide-primefaces:

<?xml version=“1.0“ encoding=“UTF-8“?>
<!DOCTYPE facelet-taglib PUBLIC “-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN“ “http://java.sun.com/dtd/facelet-taglib_1_0.dtd“>
<facelet-taglib xmlns=“http://java.sun.com/JSF/Facelet“>
   <namespace>http://jboss.org/forge/view</namespace>
   <function>
       <function-name>asList</function-name>
       <function-class>de.binaris.restaurantguide.view.ViewUtils</function-class>
       <function-signature>
             java.util.List asList(java.util.Collection)
       </function-signature>
   </function>

   <function>
       <function-name>display</function-name>
       <function-class>de.binaris.restaurantguide.view.ViewUtils</function-class>
       <function-signature>
           java.lang.String display(java.lang.Object)
       </function-signature>
   </function>

   <function>
       <function-name>count</function-name>
       <function-class>de.binaris.restaurantguide.view.ViewUtils</function-class>
       <function-signature>
             int count(java.util.Collection)
       </function-signature>
   </function>

   <function>
       <function-name>displayShort</function-name>
       <function-class>de.binaris.restaurantguide.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayShort(java.lang.Object, int)
       </function-signature>
   </function>

   <function>
       <function-name>displayRange</function-name>
       <function-class>de.binaris.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayRange(java.lang.Object,java.lang.Object)
       </function-signature>
   </function>

   <function>
       <function-name>displayFirst</function-name>
       <function-class>de.binaris.restaurantguide.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayFirst(java.lang.Object)
       </function-signature>
   </function>

   <function>
       <function-name>listExcludingSelectedOne</function-name>
       <function-class>de.binaris.restaurantguide.view.ViewUtils</function-class>
       <function-signature>
             java.util.List listExcludingSelectedOne(java.util.Collection,java.lang.Object)
       </function-signature>
   </function>  
</facelet-taglib>

Hier auch die ViewUtils-Klasse unter Verwendung generischer Typen T und Collections List<T>:

ViewUtils

package de.binaris.restaurantguide.view;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.Id;

/**
* Utilities for working with Java Server Faces views.
*/
public final class ViewUtils {

   public static <T> List<T> asList(Collection<T> collection) {
     if (collection == null) {
         return null;
     }
     return new ArrayList<T>(collection);
   }

   public static String display(Object object) {
     if (object == null) {
         return null;
     }
     try {
         // Invoke toString if declared in the class. If not found,
         // the NoSuchMethodException is caught and handled
         object.getClass().getDeclaredMethod(“toString“);
         return object.toString();
     }
     catch (NoSuchMethodException noMethodEx) {
         try {
           for (Field field : object.getClass().getDeclaredFields()) {
               // Find the primary key field and display it
               if (field.getAnnotation(Id.class) != null) {
                 // Find a matching getter and invoke it to display the key
                 for (Method method : object.getClass().getDeclaredMethods()) {
                     if (method.equals(new PropertyDescriptor(field.getName(),                    
                                         object.getClass()).getReadMethod()))
                     {
                       return method.invoke(object).toString();
                     }
                 }
               }
           }
           for (Method method : object.getClass().getDeclaredMethods()) {
               // Find the primary key as a property instead of a field, and display it
               if (method.getAnnotation(Id.class) != null) {
                 return method.invoke(object).toString();
               }
           }
         } catch (Exception ex) {
           // Unlikely, but abort and stop view generation if any exception is thrown
           throw new RuntimeException(ex);
         }
     }
     return null;
   }

   public static <T> int count(Collection<T> collection) {
     if (collection == null) {
               return 0;
     }
     return collection.size();
   }

   public static String displayRange(Object object1, Object object2) {
     String text1 = display(object1);
     String text2 = display(object2);
      if (text1 == null || text2 == null
          || text1.trim() == null || text2.trim() == null) {
           return null;
      }
     return (text1 + “-“ + text2);
   }

   public static String displayFirst(Object object) {
     String text = display(object);
      if (text == null || text.split(“\\s+“) == null
          || text.split(“\\s+“)[0] == null) {
           return null;
      }
     return (text.split(“\\s+“)[0] + “…“);
   }

   public static String displayShort(Object object, int length) {
     String text = display(object);
      if (text == null || text.split(“\\s+“) == null
           || text.split(“\\s+“)[0] == null) {
           return null;
      }
     String[] elements = text.split(“\\s+“);
     String result = ““;
      int i = 0;
      while ((result+elements[i]).length() < length) {
          result += elements[i] + “ “;
          i++;
      }
      return (result.trim() + “…“);
   }

public static <T> List<T> listExcludingSelectedOne(Collection<T> collection, T selected) {
     if (collection == null) {
         return null;
     }
     if (selected == null) {
       return new ArrayList<T>(collection);
     }
     List<T> list = new ArrayList<T>(collection);
     list.remove(selected);
     return list;
   }

   private ViewUtils() {
     // Can never be called, only by getInstance – Singleton pattern
   }

   public static ViewUtils getInstance() {
      return new ViewUtils();
   }
}

Über Tags, TagLibs und die Erweiterung bestehender und die Definition eigener Tags gibt es bereits einen Blog-Eintrag in diesem Blog und durch die soeben gezeigten Beispiele ist erkennbar, wie simpel es ist, eigene Tags für die .xhtml-Views heutiger JSF 2-Applikationen zu definieren und deren Utility functions-Signaturen im WEB-INF/classes/META-INF-Verzeichnis des classpaths als *name*-taglib.xml mit dem folgenden XML Document-Header und dem jboss-forge-view namespace zu deklarieren (s.o. forge.taglib.xml). Alle XML und XHTML-Dateien der Primefaces-Beispielapplikation finden sich im Deployment-Archiv restaurantguide-primefaces.war im /target-Unterverzeichnissen des Projekts restaurantguide-primefaces.

Die Konfiguration des JBoss WildFly Application Servers 10 Final erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2 und 9 Final und betrifft die Datasource, die MySQL-Datenbank Inno DB 5.x, Hibernate 5, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle, in Blog-Einträgen dieses Blogs bereits beschrieben.

Bei dieser Gelegenheit darf auch das sehr effektive, interessante und erfolgreiche Seminar

“TDD mit Java”

von Binaris Informatik ebenfalls erwähnt werden.

Die Primefaces Beispiel-Applikation arbeitet über die RESTful WebService-Schnittstelle auf derselben Datenbank, wie die AngularJS Beispiel-Applikation restaurantguide-angularjs, weshalb für die Primefaces Beispiel-Applikationen dasselbe mit HeidiSQL erstellte MySQL 5.x Datenbank-Skript verwendet werden kann.

Die fertige Beispiel-Applikation restaurantguide-primefaces kann hier betrachtet werden.

Hier das Beispiel-Projekt für die Eclipse Entwicklungsumgebung JBoss Developer Studio:

JBoss Developer Studio Projekt:

restaurantguide-primefaces

Hier der WildFly 10 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank für den WildFly 9 und den WildFly 10 gibt es bereits mehr Informationen in diesem Blog.

Die fertig konfigurierte Version des WildFly 10.Final mit vielen Beispiel-Applikationen der vorigen Blog-Einträge hier zum Download bereit kann runtergeladen, entpackt und gestartet werden. Dabei ist nur der Pfad für JAVA_HOME in der standalone.xml anzupassen, damit dieser auf das tatsächliche JDK 8-Verzeichnis des Server-Systems zeigt.

Die Primefaces Beispiel-Applikation dieses Blog-Eintrags kann danach selbst erneut deployt werden, ohne den bereits gestarteten WildFly 10 Application Server überhaupt stoppen oder erneut starten zu müssen. Bei laufendem Server einfach ins Server-Unterverzeichnis /standalone/deployments

– eine leere Textdatei namens restaurantguide-primefaces.war.dodeploy speichen und
– das Archiv restaurantguide-primefaces.war aus dem restaurantguide-primefaces/target-Verzeichnis speichern

Wie man sieht, macht es viel Freude, die XHTML-Views der beschriebenen Beispiel-Applikation RichFaces oder MyFaces auf die vorteilhafte Primefaces-Technologie umzustellen und ebenfalls, zuvor die Angular JS und Faces-Beispielapplikationen mittels JBoss Forge auf dem Datenmodell zu erzeugen und weiterzuentwickeln.

Es ist also sehr wahrscheinlich, dass noch weitere Blog-Einträge zu Webframeworks wie Primefaces, Angular JS und Faces und den die JEE-Spezifikation implementierenden Technologien folgen. Allen interessierten Leserinnen und Lesern weiterhin viel Freude bei der agilen Softwareentwicklung mittels Scrum und dem Test Driven Development mit Java, sowie eine schöne Sommerzeit.

WebApps – Generativ mit Angular JS, REST, JEE7, Java 8 auf JBoss WildFly 9 und 10

Die Motivation

Im Blog-Eintrag über WebApps – vom Modell zur App, mit JSF 2.2, Angular JS, REST, JPA 2 wurde beschrieben, wie leicht es ist, von einem Klassen-Diagramm (UML), genauer: Entity-Relationship-Diagramm, auch E-R Diagramm genannt, zu einer JEE7-Applikation zu kommen. Diese JEE6- und JEE7-Beispielapplikationen hier liefern mit Hilfe eines EJB 3-getriebenen Backends (Session Beans als DAOs, „DAO“-Pattern) unter Anbindung der JPA 2 Entities („Table-Per-Class“-Pattern) mit Hilfe von DTOs über fachliche RESTful ServiceInterfaces oder per Microservices mit Docker, Spring Boot, siehe auch „ServiceBroker“-Pattern hier, die benötigten Daten zur Präsentation und Bearbeitung (Änderung, Löschen, Neuanlage) in den Web-Frontends, welche die WebServices konsumieren („ServiceConsumer“-Pattern). Hier das E-R-Diagramm:

E-R-diagram
(Anm.: Die Tabelle registered_customer stellt den Restaurantkritiker („Critic“) dar.)

Die Beispiel-Applikation restaurantguide-angularjs wird dann auf dem JBoss WildFly 10 Final  Server (entspricht dem JBoss EAP 7-Server) deployt. Dabei ist die Verwendung der beiden JBoss WildFly JEE7-Application Server und die Konfiguration verschiedener Datenbanken in einem Blog-Eintrag dieses Blogs bereits beschrieben worden.

Das Durchsuchen, und die Nutzung einer Pagination der Ergebnisliste ist ebenfalls in der Beispiel-App enthalten, wie auch mit Hilfe des Angular JS Frameworks und des Bootstrap-Frameworks eine dynamische Benutzeroberfläche, die sich an beliebige Auflösungen und Display-Größen responsiv anpasst.

Die UI Frameworks

a) jQuery oder Angular JS

Die oft hierüber geführte Diskussion ist inzwischen eigentlich obsolet geworden, da es meiner Erfahrung nach eher unproblematisch ist, beide JavaScript-Frameworks in derselben Browser-Applikation zu verwenden und solange man nicht versucht, beide Frameworks auf ein und demselben HTML-Element anzuwenden, kommen diese sich auch weder bei der Event-Triggerung noch beim Event-Handling in die Quere. Hier ist ein funktionierendes Beispiel dazu mit einem jQuery-Accordion und jQuery-Carousel auf der Startseite und zusätzlich einer verlinkten Angular JS Such-Applikation im Events Header-Menü.

b) RichFaces oder Primefaces

Auch diese beiden Frameworks können parallel in einer .xhtml-Seite verwendet werden. Somit könnte eine RichFaces-richDataTable auch ein Element eines Primefaces-rating enthalten, was aber anhand der Primefaces-Beispielapplikation restaurantguide-primefaces im Bezug auf die Bewertung eines Restaurants im nächsten Blog-Eintrag nochmal besprochen werden soll.

Erstellung der Beispiel Applikation aus dem Datenmodell

Mittels Eclipse-PlugIn Umlet oder DBeaver wird das Klassendiagramm der Entities und Datenbank-Objekte erstellt und aus diesem, nach dem Anlegen der Datenbank restaurantguide per Hibernate Envers während dem WildFly Undertow Deployment mittels JBoss Forge PlugIn im JBoss Developer Studio erst der REST-WebService mit den Endpoints generiert und danach die Angular JS WebApp auf diesem RESTful WebService.

Maven JEE 7 JBoss-Artefakte und Maven Dependencies

Dabei werden in der pom.xml die folgenden Maven Dependencies verwendet und es soll nicht vergessen werden, dass die heute in Java 8 enthaltenen javax.ws.rs  REST-Packages ohne die bereits vor vielen Jahren erfolgte sehr gute Vorarbeit der Entwickler des jboss-resteasy REST-Frameworks wohl in der heutigen Form noch nicht im JDK vorhanden wären. Danke, JBoss Rockstars!

WildFly JBoss Java EE 7 Specification APIs with Tools:
– jboss-javaee-7.0-with-tools
WildFly JBoss Java EE 7 Specification APIs with Resteasy:
– jboss-javaee-7.0-with-resteasy
WildFly JBoss Java EE 7 Specification APIs with Hibernate:
– jboss-javaee-7.0-with-hibernate

Weiterhin werden die folgenden JEE Dependencies (für das Servlet API, Annotationen, JAX-RS Implementierungen, JBoss RESTEasy, Jackson, Hibernate, JPA und EJB) verwendet:

– jboss-annotations-api_1.1_spec
– jboss-jaxrs-api_2.0_spec
– resteasy-jackson2-provider

– hibernate-jpa-2.1-api
– jboss-ejb-api_3.2_spec
– hibernate-jpamodelgen
– jboss-servlet-api_3.1_spec

Einsatz von CDI

Und ebenfalls die CDI 1.1 Dependency:

– cdi-api_1.1

Die Aktivierung von CDI erfolgt, wie beschrieben, mittels beans.xml im WEB-INF Verzeichnis.

Auch über die Architektur und verwendeten Design Patterns der Beispiel-Applikationen gibt es bereits Informationen in bereits vorausgegangenen Blog-Einträgen.

Die Konfiguration des JBoss WildFly Application Servers 10 Final erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2 und 9 Final und betrifft die Datasource, die MySQL-Datenbank Inno DB 5.x, Hibernate 5, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle, in Blog-Einträgen dieses Blogs bereits beschrieben.

Bei dieser Gelegenheit darf auch das sehr effektive, interessante und erfolgreiche Seminar

“TDD mit Java”  von Binaris Informatik erwähnt werden.

Hier auch die /META-INF/persistence.xml der Beispiel-Applikation:

<xml version=“1.0″ encoding=“UTF-8″?>
<persistence version=“2.0″ xmlns=“http://java.sun.com/xml/ns/persistence“
    xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
    xsi:schemaLocation=“http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd“>
    <persistence-unit name=“RestaurantguidePU“>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>
    java:jboss/datasources/RestaurantguideDatasource
    </jta-data-source>
    <properties>
    <property name=“hibernate.hbm2ddl.auto“ value=“none“/>
    <property name=“hibernate.show_sql“ value=“false“/>
    </properties>
    </persistence-unit>
    </persistence>

Zum Erzeugen der Datenbank wird das folgende Property gesetzt:

<property name=“hibernate.hbm2ddl.auto“ value=“create-drop“/>

Damit die Datenbank danach nicht bei jedem Server-Neustart gelöscht und neuangelegt wird, wurde das Property “hibernate.hbm2ddl.auto“ danach auf den unwirksamen Wert “none“ gesetzt.

Dafür wird die folgende Datasource benötigt und ist in der standalone/configuration/standalone.xml des JBoss WildFly Servers unter den <datasources> einzutragen:

<datasource jndi-name=“java:jboss/datasources/RestaurantguideDatasource“ pool-name=“RestaurantguideDS“
    enabled=“true“>
    <connection-url>jdbc:mysql://localhost:3306/restaurantguide</connection-url>
    <driver>mysql-connector-java-5.1.34.jar</driver>
    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
    <pool>
    <min-pool-size>10</min-pool-size>
    <max-pool-size>1000</max-pool-size>
    <prefill>true</prefill>
    </pool>
    <security>
    <user-name>root</user-name>
    <password>das entsprechende Passwort</password>
    </security>
    <statement>
    <prepared-statement-cache-size>32</prepared-statement-cache-size>
    <share-prepared-statements>true</share-prepared-statements>
    </statement>
    </datasource>

Hier auch der komplette MySQL-Export der Beispiel-Applikation restaurantguide-angularjs:

Für MySQL 5: export_restaurantguide_database.txt

Die fertige Beispiel-Applikation restaurantguide-angularjs kann zusammen mit den anderen Beispiel-Applikationen hier betrachtet werden.

Hier das Beispiel-Projekte für die Eclipse-Entwicklungsumgebung JBoss Developer Studio:

restaurantguide-angularjs

Hier der WildFly 10 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8.

Die fertig konfigurierte Version des WildFly 10.Final mit vielen Beispiel-Applikationen der vorigen Blog-Einträge hier zum Download bereit kann runtergeladen, entpackt und gestartet werden. Dabei ist nur der Pfad für JAVA_HOME in der standalone.xml anzupassen, damit dieser auf das tatsächliche JDK 8-Verzeichnis des Server-Systems zeigt.

Die Angular JS Beispiel-Applikation dieses Blog-Eintrags kann danach selbst erneut deployt werden, ohne den bereits gestarteten WildFly 10 Application Server überhaupt stoppen oder erneut starten zu müssen. Bei laufendem Server einfach ins Server-Unterverzeichnis /standalone/deployments das Archiv restaurantguide-angularjs.war aus dem restaurantguide-angularjs/target-Verzeichnis speichern.

Sofort wird die Beispiel-Applikation deployt und in wenigen Sekunden gestartet und kann aufgerufen werden:

http://localhost:8080/restaurantguide-angularjs

Wie man sieht, macht es einfach Spaß, die responsiven Angular JS-Beispielapplikationen mittels JBoss Forge auf dem Datenmodell zu erzeugen und für die Umsetzung der Anforderungen weiterzuentwickeln.

Es besteht also durchaus die Möglichkeit, dass noch weitere Blog-Einträge zu Webframeworks wie Angular JS und Bootstrap auf die JEE7-Spezifikation implementierenden WebService-und Backend-Technologien folgen.

Allen interessierten Leserinnen und Lesern weiterhin viel Freude bei der agilen Softwareentwicklung mittels Scrum und dem Test Driven Development mit Java, sowie eine schöne Sommerzeit.

WebApps – Primefaces 6, JPA 2, EJB 3, PDFs parsen, iText, MySQL, REST, JEE7, WildFly

Die Motivation

Über Beispiel-Applikationen zu der sehr vorteilhaften Primefaces-Technologie gibt es bereits Blog-Einträge in diesem Blog hier. Im Blog-Eintrag über WebApps – vom Modell zur App, mit JSF 2.2, Angular JS, REST, JPA 2 wurde beschrieben, wie leicht es ist, von einem Entity-Relationship-Diagramm zu einer JEE7-Applikation zu kommen. In diesem Blog-Eintrag soll nun die nach dem zugrundeliegenden relationalen Datenmodell im vorigen Blog-Eintrag hier besprochene Primefaces Beispiel-Webapplikation jobapplicationadmin-primefaces ergänzt werden. Hier das mittels DBeaver erstellte Entity-Relationship Diagramm der jobapplication-MySQL Datenbank:

E-R-diagram
(Anm.: Die Tabelle Customer, welche den Bewerber („Job Applicant“) darstellt enthält dabei die Adresse, welche physisch in die Tabelle integriert ist und deshalb auf der Entity „Customer“ als @Embeddable Adresse annotiert wird.)

Diese weiterentwickelte, um das Such-Formular und den PDF FileParser erweiterte Admin-Applikation jobapplicationadmin-primefaces ist die Admin-Sicht für einen HR-Mitarbeiter, welcher die über die Applikation jobapplication-primefaces eingegangenen Bewerbungen (“Job Applications“) mit den zugehörigen hochgeladenen PDF-Dokumenten und einem Profilbild weiterbearbeiten möchte. Hierfür sieht er nach dem Einloggen alle Bewerber und deren persönliche Daten, Zusatzinformationen sowie hochgeladene Dokumente und kann diese öffnen, zur Weiterverarbeitung herunterladen, oder über das zusätzliche Such-Formular nach den interessierenden Suchworten durchsuchen. Die PDFs mit den gefundenen Suchworten werden dann in einer Ergebnis-Tabelle präsentiert. Falls keine PDFs mit den Suchworten gefunden werden, bleibt diese Tabelle leer (“No records found“).

Erstellung der Beispiel Applikation nach Datenmodell

Die Beispiel-Applikation jobapplicationadmin-primefaces wurde bereits im vorigen Blog-Eintrag hier nach dem Datenmodell erstellt und dann auf den Application Servern JBoss WildFly 9 Final, JBoss WildFly 10 Final and JBoss WildFly 11 Final deployt und getestet. Die Verwendung der JBoss WildFly JEE7-Application Server wurde in diesem Blog-Eintrag hier bereits einmal beschrieben. Dabei liefern die JEE6- und JEE7-Beispielapplikationen hier mit Hilfe eines EJB 3-getriebenen Backends (Session Beans als DAOs, DAO-Pattern) unter Anbindung der JPA 2 Entities (Table-Per-Class – Pattern) mit Hilfe von DTOs über fachliche RESTful ServiceInterfaces die benötigten Daten zur Präsentation und Bearbeitung (Änderung, Löschen, Neuanlage) in den Web-Frontends, welche die WebServices konsumieren (ServiceConsumer-Pattern). Der JPA-Provider ist dabei Hibernate von JBoss, welches auf dem WildFly zu konfigurieren ist, was bereits in diesem Blog-Eintrag hier beschrieben wurde.

In der pom.xml des Beispielprojekts jobapplicationadmin-primefaces1 ist nach erfolgtem Download erkennbar, dass auch hier die bekannten JEE 7 Artefakte für den JBoss WildFly verwendet und importiert wurden:

Maven JEE 7 JBoss-Artefakte und Maven Dependencies

WildFly JBoss Java EE 7 Specification APIs with Tools:
– jboss-javaee-7.0-with-tools
WildFly JBoss Java EE 7 Specification APIs with Resteasy:
– jboss-javaee-7.0-with-resteasy
WildFly JBoss Java EE 7 Specification APIs with Hibernate:
– jboss-javaee-7.0-with-hibernate

Weiterhin werden die folgenden JEE Dependencies (für das Servlet API, Annotationen, JAX-RS Implementierungen, JBoss RESTEasy, Jackson, Hibernate, JPA und EJB) verwendet:

– jboss-annotations-api_1.1_spec
– jboss-jaxrs-api_2.0_spec
– resteasy-jackson2-provider

– hibernate-jpa-2.1-api
– jboss-ejb-api_3.2_spec
– hibernate-jpamodelgen
– jboss-servlet-api_3.1_spec

Und ebenfalls die CDI 1.1 Dependency:

– cdi-api_1.1

Einsatz von CDI

Die Aktivierung von CDI erfolgt, wie beschrieben, mittels beans.xml im WEB-INF Verzeichnis.

Auch über die Architektur und die verwendeten Design Patterns der Beispiel-Applikationen gibt es bereits Informationen in einem Blog-Eintrag hier und bereits vorausgegangenen Blog-Einträgen.

Primefaces 6 und iText Dependencies:

Hat man erst einmal die JPA 2.2 Entities definiert und, wie beschrieben, mittels JBoss Forge die Beispiel-Webapplikationen für die ausgewählte Frontend-Technologie (Angular JS oder Faces) erzeugt und rebrandet, ist z. B. auch die Migration einer Faces Beispiel-Applikation auf Primefaces leicht durchführbar und wurde bereits in einem vorigen Blog-Eintrag hier beschrieben.

Die Einbindung der erforderlichen Primefaces-UI-Bibliothek primefaces-6.0.jar erfolgt dabei ganz simpel übers Hinzufügen der entsprechenden Maven Primefaces Dependency in der pom.xml.

<dependency>
    <groupId>org.primefaces</groupId>
    <artifactId>primefaces</artifactId>
    <version>6.0</version>
</dependency>

Zusätzlich sind für das Durchsuchen der hochgeladenen PDFs die folgende BouncyCastle– und die iText-Dependency erforderlich:

<dependency>
     <groupId>org.bouncycastle</groupId>
     <artifactId>bcprov-jdk15on</artifactId>
     <version>1.48</version>
</dependency>

<dependency>
     <groupId>com.itextpdf</groupId>
     <artifactId>itextpdf</artifactId>
     <version>5.4.5</version>
</dependency>

(Bouncy Castle wird vom PDF FileParser benötigt, um kodierte ASN.1 Objekte aus dem PDF zu lesen und in lesbare Text-Fragmente zu dekodieren.)

Allein durch Änderung dieser Einträge in der pom.xml kann jederzeit auch auf die gewünschte Primefaces-Version umgestellt werden, ebenso auf eine höhere iText- und BouncyCastle-Version. Bei der Ausprogrammierung der XHTML-Views auf Primefaces sind der Primefaces Showcase und der neue Primefaces 6.0 Users Guide (PDF) sehr hilfreich. Ebenfalls wurde das sehr gute bei DZone erhältliche PDF zur JSTL (Java Server Pages Template Library) verwendet. Der größte Aufwand einer Migration besteht hierbei im Austausch der Standard MyFaces-Tags (h: Präfix) durch die Primefaces-Tags (p: Präfix), ist also für die simplen Beispiel-Applikationen hier leicht umsetzbar. Weitere Informationen zur Migration auf Primefaces sind bereits in einem vorigen Blog-Eintrag hier vorhanden.

Aktiviert werden die Primefaces-Tags in der gewünschten XHTML-Seite mittels folgendem Namespace Eintrag im Dokumenten-Kopf der XHTML-View xmlns:p=“http://primefaces.org/ui und die zusätzliche Funktionalität der JSTL-Tags wird entsprechend, wie in den MyFaces-Views auch, per xmlns:c=“http://java.sun.com/jsp/jstl/core verfügbar gemacht.

Durch die Verwendung von CDI 1.1 haben die JSF ManagedBeans stattdessen die Annotation @Named und bleiben ansonsten nahezu identisch zu den ManagedBeans der MyFaces-Applikationen. Weitere Informationen zu JSF 2.2, CDI und Primefaces finden sich auch hier im Blog von Balus C. Detail-Informationen zur JavaScript-Bibliothek jQuery, die vom Primefaces-Framework sehr intensiv verwendet wird, finden sich hier: jquery.org

Die search.xhtml-Seite mit dem Suchwort-Formular und der Ergebnis-Tabelle und ebenfalls die erforderlichen Erweiterungen der FileUploadBean mit der Such-Methode und deren Hilfsmethoden, die sich auch leicht in eine PDFFileParser-Utility Klasse refaktorisieren lassen, finden sich beide im Beispiel-Projekt.

Alle XML und XHTML-Dateien der kompletten Primefaces-Beispielapplikation finden sich im Deployment-Archiv jobapplicationadmin-primefaces.war im /target-Unterverzeichnissen des Projekts jobapplicationadmin-primefaces1.

WildFly Anbindung an MySQL5 und deklarative WildFly 11 Hibernate-Konfiguration

Die Konfiguration des JBoss WildFly Application Servers 11 Final erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2, 9 und 10 Final und betrifft die Datasource, die MySQL-Datenbank Inno DB 5.x, Hibernate 5, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle ein wichtiges Thema, welches noch genauer beschrieben werden wird. Die Anbindung an die relationale  Datenbank MySQL 5 erfolgt übrigens analog für die JBoss Application Server WildFly 8.1, 8.2, 9, 10 und WildFly 11.

Je nach verwendeter Datenbank kann in der persistence.xml im Deployment-Paket der Beispiel-App jobapplication-primefaces.war ein entsprechender Datenbank-Dialekt eingetragen werden:

Hier die /META-INF/persistence.xml der Beispiel-Applikation für MySQL5:

    <xml version=“1.0″ encoding=“UTF-8″?>
    <persistence version=“2.0″ xmlns=“http://java.sun.com/xml/ns/persistence“
    xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
    xsi:schemaLocation=“http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd“>
    <persistence-unit name=“JobapplicationPU“>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>
            java:jboss/datasources/JobapplicationDatasource
    </jta-data-source>
    <properties>
    <property name=“hibernate.hbm2ddl.auto“ value=“none“/>
    <property name=“hibernate.show_sql“ value=“false“/>
    </properties>
    </persistence-unit>
    </persistence>

Dafür wird je Datenbank die folgende Datasource benötigt und ist in der standalone/configuration/standalone.xml des JBoss WildFly Servers unter den <datasources> einzutragen:

Für MySQL 5:

    <datasource jndi-name=“java:jboss/datasources/JobapplicationDatasource“ pool-name=“JobapplicationDS“ enabled=“true“>
<connection-url>jdbc:mysql://localhost:3306/jobapplication</connection-url>

    <driver>mysql-connector-java-5.1.34.jar</driver>
    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
    <pool>
    <min-pool-size>10</min-pool-size>
    <max-pool-size>100</max-pool-size>
    <prefill>true</prefill>
    </pool>
    <security>
    <user-name>root</user-name>
    <password>das entsprechende Passwort</password>
    </security>
    <statement>
    <prepared-statement-cache-size>32</prepared-statement-cache-size>
    <share-prepared-statements>true</share-prepared-statements>
    </statement>
    </datasource>

Für die erfolgreiche Anbindung der soeben deklarierten Datasoures werden die Datenbank-Treiber auf Modul-Ebene des JBoss WildFly konfiguriert, wie noch genauer beschrieben wird.

Damit die Datasources die soeben konfigurierten Treiber auch finden, werden diese in der /standalone/configuration/standalone.xml bei den <datasources>deklariert:

Für MySQL 5:

<driver name=“mysql-connector-java-5.1.34.jar“ module=“com.mysql“>
   <driver-class>com.mysql.jdbc.Driver</driver-class>
   <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
   </xa-datasource-class>
</driver>

Die Hibernate-Konfiguration des WildFly 11 Final Servers ist ebenfalls leicht durchführbar. Hierfür werden im WildFly11 Server-Verzeichnis wildfly-11.0.0.Final/modules/system/layers/base/org/hibernate/main folgende Dateien hinterlegt:

– hibernate-core-5.1.10.Final.jar
– hibernate-entitymanager-5.1.10.Final.jar
– hibernate-envers-5.1.10.Final.jar
– hibernate-java8-5.1.10.Final.jar
– jipijapa-hibernate5-11.0.0.Final.jar
– module.xml
– mysql-connector-java-5.1.34.jar
– mysql-connector-java-5.1.34.jar.index

Die fertige Beispiel-Applikation jobapplicationadmin-primefaces kann leicht selbst deployt werden und wird ebenfalls nicht auf dem Test-Server deployt, um den Eindruck zu vermeiden, man könnte sich darüber real bewerben oder reale Bewerbungen bearbeiten. Aus demselben Grund wurden in der Beispiel-Applikation auch das Firmen-Logo durch ein neutrales Emblem ersetzt und der Link auf binaris.de entfernt. Denn bei Binaris Informatik bewirbt man sich nach wie vor am besten hier.

Bei dieser Gelegenheit darf auch das sehr effektive, interessante und erfolgreiche Seminar

“TDD mit Java”

hier von Binaris Informatik
ebenfalls positiv erwähnt werden.

Hier die Beispiel-Projekte für die Entwicklungsumgebungen JBoss Developer Studio und intelliJ 15:

JBoss Developer Studio Projekt:

jobapplicationadmin-primefaces

intelliJ Projekt:

jobapplicationadmin-primefaces

Hier der WildFly 9 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 7.

Hier der WildFly 10 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank für den WildFly 9 und den WildFly 10 gibt es hier mehr Informationen in diesem Blog.

Die fertig konfigurierte Version des WildFly 10.0.0.Final mit vielen Beispiel-Applikationen der vorigen Blog-Einträge hier zum Download bereit, kann runtergeladen, entpackt und gestartet werden. Dabei ist nur der Pfad für JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 8 – Verzeichnis des Server-Systems zeigt.

Hier auch der WildFly 11 als Zip-Archiv zum Download und Entpacken, für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank wird ebenfalls auf bereits vorhandene Blog-Einträge hier verwiesen, da die Konfigurationen analog zum WildFly 9 und WildFly 10 durchzuführen sind.

Der fertig konfigurierte WildFly 11 mit vielen Beispiel-Applikationen der vorangegangenen Blog-Einträge ist hier zum Download verfügbar, kann runtergeladen, entpackt und gestartet werden. Auch hier ist nur der Pfad des JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 9 – Verzeichnis des Server-Systems zeigt.

Mehr Informationen zum Java 9 Release gibt es hier:

https://www.technotification.com/2017/09/java-9-is-finally-released.html

Herunterladen kann man sich das Java 9 für die gewünschte Betriebssystem-Plattform hier:

http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html

In Fällen mit Migrations-Bedarf gibt es hier weitere Informationen.

Hier die Release-Notes zu Java 9:

http://www.oracle.com/technetwork/java/javase/9-relnotes-3622618.html

Oracle Support für das Oracle JDK 8:
Nach January 2019 läuft nun der Oracle Support für das Oracle JDK 8 aus, weshalb es dann keine Updates mehr für Java SE 8 geben wird. Weiterhin wird ein entsprechender Oracle Support Vertrag für die produktive Verwendung der Java Versionen 6, 7, 9, 10 und 11 erforderlich werden. Mehr information gibt es in diesem Blog hier.

Oracle Java wird also ab Februar 2019 produktiv nicht mehr gebührenfrei einsetzbar sein, weshalb es von RedHat frei einsetzbare OpenJDK Java Versionen gibt, welche von RedHat auch für Endanwender und Unternehmen kostenfrei supportet werden. Hierfür ist lediglich eine Red Hat Enterprise Linux oder Middleware Subscription erforderlich.

Die SQL-Skripte zum Anlegen und Befüllen der MySQL Beispiel-Datenbanken finden sich verlinkt in den Blog-Einträgen wieder, die hier durchsucht werden können, durch Eingabe eines Stichworts des Titels oder Blog-Eintrag Texts im Feld Suche… der Eingabemaske.

Hier auch nochmal die ausführliche Dokumentation einer weiteren JEE Beispielapplikation mit REST-Webservices getriebenem Angular JS Frontend. Und hier noch eine weitere SPA (Single Page Appliction) Beispiel-Applikation, bei der das Testen des Backends mittels Arquillian und das integrative Testen des Frontends mittels Selenium (Workflow und UX Elemente) und QUnit  (Javascript-Framework zum Test-Aufruf der REST-Endpoints aus einer Browser-View) ebenfalls ausführlich beschrieben sind. Hier auch die passende Architekur-Bewertung zu den SPAs und REST-WebServices auf jaxenter.de.

Die Primefaces Beispiel-Applikation dieses Blog-Eintrags kann danach selbst erneut deployt werden, ohne den bereits gestarteten WildFly 10 Application Server überhaupt stoppen oder erneut starten zu müssen. Bei laufendem Server einfach ins Server-Unterverzeichnis /standalone/deployments

– eine leere Textdatei namens jobapplicationadmin-primefaces.war.dodeploy speichen und
– das Archiv jobapplicationadmin-primefaces.war aus dem jobapplicationadmin-primefaces1/target-Verzeichnis speichern

Wie man sieht, macht es viel Freude, JEE-Applikationen mit der vorteilhaften Primefaces-Technologie zu entwickeln und ebenfalls, zuvor die Faces-Beispielapplikationen mittels JBoss Forge auf dem Datenmodell zu erzeugen und weiterzuentwickeln.

Es ist also sehr wahrscheinlich, dass noch weitere Blog-Einträge zu Webframeworks wie Primefaces, Angular JS und Faces und den die JEE-Spezifikation implementierenden Technologien folgen.

Allen interessierten Leserinnen und Lesern weiterhin viel Freude bei der agilen Softwareentwicklung mittels Scrum und dem Test Driven Development mit Java, sowie eine schöne, fröhliche und verantwortungsvolle Karnevals-Session und einen angenehmen Frühling.

WebApps – JSF 2, Primefaces, FileDownloads, JPA 2, EJB 3, JEE7, REST, MySQL, WildFly

Die Motivation

Über Beispiel-Applikationen zu der der sehr vorteilhaften Primefaces 6-Technologie gibt es bereits Blog-Einträge in diesem Blog hier. Im Blog-Eintrag über WebApps – vom Modell zur App, mit JSF 2.2, Angular JS, REST, JPA 2 hier wurde beschrieben, wie leicht es ist, von einem Klassen-Diagramm (UML), genauer: Entity-Relationship-Diagramm, auch E-R Diagramm genannt, zu einer JEE7-Applikation zu kommen. In diesem Blog-Eintrag soll nun nach dem zugrundeliegenden relationalen Datenmodell eine Primefaces 6 Beispiel-Webapplikation jobapplicationadmin-primefaces für eine MySQL 5 Datenbank erstellt werden. Dabei werden als Basis-Frontendtechnologien JSF 2 und Primefaces 6 verwendet. Weiterhin wird der Einsatz moderner Tag-Libs in den XHTML-Seiten der JEE7-Applikation erklärt.

Erstellung der Beispiel Applikation nach Datenmodell

Mittels JBoss Forge Eclipse PlugIn wird die Primefaces 6 Beispiel-Applikation jobapplicationadmin-primefaces auf dem Datenmodell mit den JPA 2 Entities erstellt unter Einsatz von JSF 2 und der robusten, elegant gestylten, etablierten, optimalen Primefaces Frontend-Technologie. Hier das mittels DBeaver erstellte Entity-Relationship Diagramm der jobapplication-MySQL Datenbank:

E-R-diagram
(Anm.: Die Tabelle Customer, welche den Bewerber („Job Applicant“) darstellt enthält dabei die Adresse, welche physisch in die Tabelle integriert ist und deshalb auf der Entity „Customer“ als @Embeddable Adresse annotiert wird.

Die weiterentwickelte Beispiel-Applikation jobapplicationadmin-primefaces wird dann auf den JBoss WildFly 9 Final und JBoss WildFly 10 Final Application Servern deployt und getestet. Die Verwendung der JBoss WildFly JEE7-Application Server wurde in diesem Blog-Eintrag hier bereits einmal beschrieben. Dabei liefern die JEE6- und JEE7-Beispielapplikationen hier mit Hilfe eines EJB 3-getriebenen Backends (Session Beans als DAOs, DAO-Pattern) unter Anbindung der JPA 2 Entities (Table-Per-Class – Pattern) mit Hilfe von DTOs über fachliche RESTful ServiceInterfaces die benötigten Daten zur Präsentation und Bearbeitung (Änderung, Löschen, Neuanlage) in den Web-Frontends, welche die WebServices konsumieren (ServiceConsumer-Pattern). Der JPA-Provider ist dabei Hibernate von JBoss, welches auf dem WildFly zu konfigurieren ist.

Wie die Applikation jobapplication-primefaces mittels JBoss Forge erstellt werden kann, ist bereits in diesem Blog-Eintrag hier beschrieben worden, und wie in der pom.xml des jeweiligen Beispielprojekts nach erfolgtem Download erkennbar ist, wurden auch in der Applikation jobapplicationadmin-primefaces die folgenden JEE 7 Artefakte für den JBoss WildFly identifiziert, verwendet und importiert:

Maven JEE 7 JBoss-Artefakte und Maven Dependencies

WildFly JBoss Java EE 7 Specification APIs with Tools:
– jboss-javaee-7.0-with-tools
WildFly JBoss Java EE 7 Specification APIs with Resteasy:
– jboss-javaee-7.0-with-resteasy
WildFly JBoss Java EE 7 Specification APIs with Hibernate:
– jboss-javaee-7.0-with-hibernate

Weiterhin werden die folgenden JEE Dependencies (für das Servlet API, Annotationen, JAX-RS Implementierungen, JBoss RESTEasy, Jackson, Hibernate, JPA und EJB) verwendet:

– jboss-annotations-api_1.1_spec
– jboss-jaxrs-api_2.0_spec
– resteasy-jackson2-provider

– hibernate-jpa-2.1-api
– jboss-ejb-api_3.2_spec
– hibernate-jpamodelgen
– jboss-servlet-api_3.1_spec

Und ebenfalls die CDI 1.1 Dependency:

– cdi-api_1.1

Einsatz von CDI

Über CDI und JavaEE gibt es bereits Blog-Einträge in diesem Blog hier und hier. Die Aktivierung von CDI erfolgt, wie beschrieben, mittels beans.xml im WEB-INF Verzeichnis.

Auch über die Architektur und die verwendeten Design Patterns der Beispiel-Applikationen gibt es bereits Informationen in einem Blog-Eintrag hier und bereits vorausgegangenen Blog-Einträgen.

Primefaces 6:

Hat man erst einmal die JPA 2.2 Entities definiert und mittels JBoss Forge die Beispiel-Webapplikationen für die ausgewählte Frontend-Technologie (Angular JS oder Faces) erzeugt und rebrandet, ist die Migration der Faces Beispiel-Applikation leicht durchführbar und wurde bereits in den vorigen Blog-Einträgen beschrieben.

Die Einbindung der erforderlichen Primefaces-UI-Bibliothek primefaces-6.0.jar erfolgt dabei ganz simpel übers Hinzufügen der entsprechenden Maven Primefaces Dependency in der pom.xml.

<dependency>
    <groupId>org.primefaces</groupId>
    <artifactId>primefaces</artifactId>
    <version>6.0</version>
</dependency>

Allein durch Änderung dieses Eintrags in der pom.xml kann jederzeit auch auf die gewünschte Primefaces-Version umgestellt werden. Bei der Ausprogrammierung der XHTML-Views auf Primefaces sind der Primefaces Showcase und der neue Primefaces 6.0 Users Guide (PDF) sehr hilfreich. Der größte Aufwand der Migration besteht hierbei im Austausch der Standard MyFaces-Tags (h: Präfix) durch die Primefaces-Tags (p: Präfix) ist also für die simplen Beispiel-Applikationen leicht umsetzbar. Ebenfalls wurde das sehr gute bei DZone erhältliche PDF zur JSTL (Java Server Pages Template Library) verwendet.

Aktiviert werden die Primefaces-Tags in der gewünschten XHTML-Seite mittels folgendem Namespace Eintrag im Dokumenten-Kopf der XHTML-View xmlns:p=“http://primefaces.org/ui und die zusätzliche Funktionalität der JSTL-Tags wird entsprechend, wie in den MyFaces-Views auch, per xmlns:c=“http://java.sun.com/jsp/jstl/core verfügbar gemacht.

Durch die Verwendung von CDI 1.1 haben die JSF ManagedBeans stattdessen die Annotation @Named und bleiben ansonsten nahezu identisch zu den ManagedBeans der MyFaces-Applikationen. Weitere Informationen zu JSF 2.2, CDI und Primefaces finden sich auch hier im Blog von Balus C. Detail-Informationen zur JavaScript-Bibliothek jQuery, die vom Primefaces-Framework sehr intensiv verwendet wird, finden sich hier: jquery.org

forge.taglib.xml:

Die in den Beispiel-Applikationen verwendete, moderne Forge TagLib kann sehr einfach erweitert werden, indem die zusätzlich benötigten Methoden in der ViewUtils-Klasse ergänzt werden und deren Signaturen in der forge.taglib.xml im Verzeichnis src/main/webapp/WEB-INF/classes/META-INF/ bekanntgemacht werden, also genau wie bei klassischen TagLibs mit dem Unterschied, dass die verwendeten Tags innerhalb der Applikation in der ViewUtils-Klasse implementiert werden, was für die Applikation zusätzliche Sicherheit bringt. Diese Tags sind für jede Applikation sehr leicht adaptierbar und können genau auf die Applikation zugeschnitten werden. Die TagLib wird in der entsprechenden .xhtml-View über den Eintrag xmlns:forgeview=“http://jboss.org/forge/view“ mit dem Prefix forgeview unter der DOCTYPE-Definition im ui:composition eingebunden und mittels forgeview-Prefix per Expression Language (EL) an der gewünschten Stelle mit den richtigen Input-Parametern aufgerufen. Hier die forge.taglib.xml für die Beispiel-Applikation jobapplicationadmin-primefaces:

<?xml version=“1.0“ encoding=“UTF-8“?>
<!DOCTYPE facelet-taglib PUBLIC “-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN“ “http://java.sun.com/dtd/facelet-taglib_1_0.dtd“>
<facelet-taglib xmlns=“http://java.sun.com/JSF/Facelet“>
   <namespace>http://jboss.org/forge/view</namespace>
   <function>
       <function-name>asList</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             java.util.List asList(java.util.Collection)
       </function-signature>
   </function>
  
   <function>
       <function-name>display</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
           java.lang.String display(java.lang.Object)
       </function-signature>
   </function>
               
   <function>
       <function-name>count</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             int count(java.util.Collection)
       </function-signature>
   </function>
               
   <function>
       <function-name>displayShort</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayShort(java.lang.Object, int)
       </function-signature>
   </function>
               
   <function>
       <function-name>displayRange</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayRange(java.lang.Object,java.lang.Object)
       </function-signature>
   </function>

   <function>
       <function-name>displayFirst</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayFirst(java.lang.Object)
       </function-signature>
   </function>

   <function>
       <function-name>listExcludingSelectedOne</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             java.util.List listExcludingSelectedOne(java.util.Collection,java.lang.Object)
       </function-signature>
   </function>  
</facelet-taglib>

Hier auch die ViewUtils-Klasse unter Verwendung generischer Typen T und Collections List<T>:

ViewUtils:

package de.binaris.jobapplication.view;
 
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
 
import javax.persistence.Id;
 
/**
* Utilities for working with Java Server Faces views.
*/
public final class ViewUtils {
 
   public static <T> List<T> asList(Collection<T> collection) {
     if (collection == null) {
         return null;
     }
     return new ArrayList<T>(collection);
   }
 
   public static String display(Object object) {
     if (object == null) {
         return null;
     }
     try {
         // Invoke toString if declared in the class. If not found,
         // the NoSuchMethodException is caught and handled
         object.getClass().getDeclaredMethod(“toString“);
         return object.toString();
     }
     catch (NoSuchMethodException noMethodEx) {
         try {
           for (Field field : object.getClass().getDeclaredFields()) {
               // Find the primary key field and display it
               if (field.getAnnotation(Id.class) != null) {
                 // Find a matching getter and invoke it to display the key
                 for (Method method : object.getClass().getDeclaredMethods()) {
                     if (method.equals(new PropertyDescriptor(field.getName(),                    
                                         object.getClass()).getReadMethod()))
                     {
                       return method.invoke(object).toString();
                     }
                 }
               }
           }
           for (Method method : object.getClass().getDeclaredMethods()) {
               // Find the primary key as a property instead of a field, and display it
               if (method.getAnnotation(Id.class) != null) {
                 return method.invoke(object).toString();
               }
           }
         } catch (Exception ex) {
           // Unlikely, but abort and stop view generation if any exception is thrown
           throw new RuntimeException(ex);
         }
     }
     return null;
   }
 
   public static <T> int count(Collection<T> collection) {
     if (collection == null) {
               return 0;
     }
     return collection.size();
   }
 
   public static String displayRange(Object object1, Object object2) {
     String text1 = display(object1);
     String text2 = display(object2);
      if (text1 == null || text2 == null
          || text1.trim() == null || text2.trim() == null) {
           return null;
      }
     return (text1 + “-“ + text2);
   }
               
   public static String displayFirst(Object object) {
     String text = display(object);
      if (text == null || text.split(“\\s+“) == null
          || text.split(“\\s+“)[0] == null) {
           return null;
      }
     return (text.split(“\\s+“)[0] + “…“);
   }
 
   public static String displayShort(Object object, int length) {
     String text = display(object);
      if (text == null || text.split(“[‚.‘]“) == null
           || text.split(“[‚.‘]“)[0] == null) {
           return null;
      }
     String[] elements = text.split(“[‚.‘]“);
     String result = ““;
      if (text.length() < length) {
         return text;
      } else {
         result = text.substring(0,length-4) + „…“;
         return result;
      }
   }

   public static <T> List<T> listExcludingSelectedOne(Collection<T> collection, T selected) {
     if (collection == null) {
         return null;
     }
     if (selected == null) {
       return new ArrayList<T>(collection);
     }
     List<T> list = new ArrayList<T>(collection);
     list.remove(selected);
     return list;
   }
 
   private ViewUtils() {
     // Can never be called, only by getInstance – Singleton pattern
   }

   public static ViewUtils getInstance() {
      return new ViewUtils();
   }
}

Über Tags, TagLibs und die Erweiterung bestehender und die Definition eigener Tags gibt es bereits einen Blog-Eintrag in diesem Blog hier und durch die soeben gezeigten Beispiele ist erkennbar, wie simpel es ist, eigene Tags für die .xhtml-Views heutiger JSF 2-Applikationen zu definieren und deren Utility functions-Signaturen im WEB-INF/classes/META-INF-Verzeichnis des classpaths als *name*-taglib.xml mit dem genannten XML Document-Header und dem jboss-forge-view namespace zu deklarieren (s.o. forge.taglib.xml).

Alle XML und XHTML-Dateien der Primefaces-Beispielapplikation finden sich im Deployment-Archiv jobapplicationadmin-primefaces.war im /target-Unterverzeichnissen des Projekts jobapplicationadmin-primefaces.

Primefaces File Download

Die Admin-Applikation jobapplicationadmin-primefaces stellt nun die Admin-Sicht für einen HR-Mitarbeiter dar, welcher die über die Applikation jobapplication-primefaces eingegangenen Bewerbungen (“Job Applications“) mit den zugehörigen hochgeladenene PDF-Dokumenten und einem Profilbild weiterbearbeiten möchte. Hierfür sieht der eingeloggte Admin alle Bewerber und deren persönliche Daten, Zusatzinformationen sowie hochgeladenen Dokumente und kann diese öffnen oder zur Weiterverarbeitung herunterladen. Hierfür gibt es in der webapp/fileUpload/view.xhtml, um z. B. einen CV herunterzuladen das folgende Element:

<h:commandButton value=“Open/Download“>
        <p:fileDownload value=“#{fileUploadBean.cvStream}“ />
</h:commandButton>

Und in der Session Bean “FileUploadBean“ wird der StreamedContent cvStream über einen entsprechenden getter getCvStream() verfügbar. Folgendermaßen wird der DefaultStreamedContent erhältlich, der mittels ByteArrayInputStream den byte[]-Inhalt der MEDIUMBLOB-Column “cv“ der MySQL-Tabelle file_upload (Entity FileUpload) konvertiert:

public StreamedContent getCvStream() {

        String contentType = „application/pdf“;
StreamedContent cvStream =

            new DefaultStreamedContent(
new ByteArrayInputStream(

                        fileUpload.getCv()),
contentType,
fileUpload.getCvPath());
return cvStream;
}

Konfiguration des JBoss WildFly Application Servers

Die Konfiguration des JBoss WildFly Application Servers 10 Final erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2 und 9 Final, 10 Final sowie 11 Final und betrifft die Datasource, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle in diesem Blog-Eintrag hier und in vorigen Blog-Einträgen bereits beschrieben. Wie die MySQL-Datenbank Inno DB 5.x zu konfigurieren ist, wurde in einem bereits vorhandenen Blog-Eintrag hier bereits beschrieben.

Die Primefaces Beispiel-Applikation arbeitet über die RESTful WebService-Schnittstelle auf der MySQL-InnoDB. Für die Primefaces Beispiel-Applikationen kann das mit HeidiSQL erstellte MySQL 5.x Datenbank-Skript verwendet werden.

WildFly Anbindung an MySQL5 und deklarative WildFly 11 Hibernate-Konfiguration

Die Konfiguration des JBoss WildFly Application Servers 11 Final erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2, 9 und 10 Final und betrifft die Datasource, die MySQL-Datenbank Inno DB 5.x, Hibernate 5, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle ein wichtiges Thema, welches noch genauer beschrieben werden wird. Die Anbindung an die relationale  Datenbank MySQL 5 erfolgt übrigens analog für die JBoss Application Server WildFly 8.1, 8.2, 9, 10 und WildFly 11.

Je nach verwendeter Datenbank kann in der persistence.xml im Deployment-Paket der Beispiel-App jobapplication-primefaces.war ein entsprechender Datenbank-Dialekt eingetragen werden:

Hier die /META-INF/persistence.xml der Beispiel-Applikation für MySQL5:

    <xml version=“1.0″ encoding=“UTF-8″?>
    <persistence version=“2.0″ xmlns=“http://java.sun.com/xml/ns/persistence“
    xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
    xsi:schemaLocation=“http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd“>
    <persistence-unit name=“JobapplicationPU“>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>
            java:jboss/datasources/JobapplicationDatasource
    </jta-data-source>
    <properties>
    <property name=“hibernate.hbm2ddl.auto“ value=“none“/>
    <property name=“hibernate.show_sql“ value=“false“/>
    </properties>
    </persistence-unit>
    </persistence>

Dafür wird je Datenbank die folgende Datasource benötigt und ist in der standalone/configuration/standalone.xml des JBoss WildFly Servers unter den <datasources> einzutragen:

Für MySQL 5:

    <datasource jndi-name=“java:jboss/datasources/JobapplicationDatasource“ pool-name=“JobapplicationDS“ enabled=“true“>
<connection-url>jdbc:mysql://localhost:3306/jobapplication</connection-url>

    <driver>mysql-connector-java-5.1.34.jar</driver>
    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
    <pool>
    <min-pool-size>10</min-pool-size>
    <max-pool-size>100</max-pool-size>
    <prefill>true</prefill>
    </pool>
    <security>
    <user-name>root</user-name>
    <password>das entsprechende Passwort</password>
    </security>
    <statement>
    <prepared-statement-cache-size>32</prepared-statement-cache-size>
    <share-prepared-statements>true</share-prepared-statements>
    </statement>
    </datasource>

Für die erfolgreiche Anbindung der soeben deklarierten Datasoures werden die Datenbank-Treiber auf Modul-Ebene des JBoss WildFly konfiguriert, wie noch genauer beschrieben wird.

Damit die Datasources die soeben konfigurierten Treiber auch finden, werden diese in der /standalone/configuration/standalone.xml bei den <datasources>deklariert:

Für MySQL 5:

<driver name=“mysql-connector-java-5.1.34.jar“ module=“com.mysql“>
   <driver-class>com.mysql.jdbc.Driver</driver-class>
   <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
   </xa-datasource-class>
</driver>

Die Hibernate-Konfiguration des WildFly 11 Final Servers ist ebenfalls leicht durchführbar. Hierfür werden im WildFly11 Server-Verzeichnis wildfly-11.0.0.Final/modules/system/layers/base/org/hibernate/main folgende Dateien hinterlegt:

– hibernate-core-5.1.10.Final.jar
– hibernate-entitymanager-5.1.10.Final.jar
– hibernate-envers-5.1.10.Final.jar
– hibernate-java8-5.1.10.Final.jar
– jipijapa-hibernate5-11.0.0.Final.jar
– module.xml
– mysql-connector-java-5.1.34.jar
– mysql-connector-java-5.1.34.jar.index

Die fertige Beispiel-Applikation jobapplicationadmin-primefaces kann leicht selbst deployt werden und wird ebenfalls nicht auf dem Test-Server deployt, um den Eindruck zu vermeiden, man könnte sich darüber real bewerben oder reale Bewerbungen bearbeiten. Aus demselben Grund wurden in der Beispiel-Applikation auch das Firmen-Logo durch ein neutrales Emblem ersetzt und der Link auf binaris.de entfernt. Denn bei Binaris Informatik bewirbt man sich nach wie vor am besten hier.

Bei dieser Gelegenheit darf auch das sehr effektive, interessante und erfolgreiche Seminar

“TDD mit Java”

hier von Binaris Informatik
ebenfalls positiv erwähnt werden.

Hier die Beispiel-Projekte für die Entwicklungsumgebungen JBoss Developer Studio und intelliJ 15:

JBoss Developer Studio Projekt:

jobapplicationadmin-primefaces

intelliJ Projekt:

jobapplicationadmin-primefaces

Hier der WildFly 9 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 7.

Hier der WildFly 10 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank für den WildFly 9 und den WildFly 10 gibt es hier mehr Informationen in diesem Blog.

Die fertig konfigurierte Version des WildFly 10.0.0.Final mit vielen Beispiel-Applikationen der vorigen Blog-Einträge hier zum Download bereit, kann runtergeladen, entpackt und gestartet werden. Dabei ist nur der Pfad für JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 8 – Verzeichnis des Server-Systems zeigt.

Hier auch der WildFly 11 als Zip-Archiv zum Download und Entpacken, für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank wird ebenfalls auf bereits vorhandene Blog-Einträge hier verwiesen, da die Konfigurationen analog zum WildFly 9 und WildFly 10 durchzuführen sind.

Der fertig konfigurierte WildFly 11 mit vielen Beispiel-Applikationen der vorangegangenen Blog-Einträge ist hier zum Download verfügbar, kann runtergeladen, entpackt und gestartet werden. Auch hier ist nur der Pfad des JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 9 – Verzeichnis des Server-Systems zeigt.

Mehr Informationen zum Java 9 Release gibt es hier:

https://www.technotification.com/2017/09/java-9-is-finally-released.html

Herunterladen kann man sich das Java 9 für die gewünschte Betriebssystem-Plattform hier:

http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html

In Fällen mit Migrations-Bedarf gibt es hier weitere Informationen.

Hier die Release-Notes zu Java 9:

http://www.oracle.com/technetwork/java/javase/9-relnotes-3622618.html

Oracle Support für das Oracle JDK 8:
Nach January 2019 läuft nun der Oracle Support für das Oracle JDK 8 aus, weshalb es dann keine Updates mehr für Java SE 8 geben wird. Weiterhin wird ein entsprechender Oracle Support Vertrag für die produktive Verwendung der Java Versionen 6, 7, 9, 10 und 11 erforderlich werden. Mehr information gibt es in diesem Blog hier.

Oracle Java wird also ab Februar 2019 produktiv nicht mehr gebührenfrei einsetzbar sein, weshalb es von RedHat frei einsetzbare OpenJDK Java Versionen gibt, welche von RedHat auch für Endanwender und Unternehmen kostenfrei supportet werden. Hierfür ist lediglich eine Red Hat Enterprise Linux oder Middleware Subscription erforderlich.

Die SQL-Skripte zum Anlegen und Befüllen der MySQL Beispiel-Datenbanken finden sich verlinkt in den Blog-Einträgen wieder, die hier durchsucht werden können, durch Eingabe eines Stichworts des Titels oder Blog-Eintrag Texts im Feld Suche… der Eingabemaske.

Hier auch nochmal die ausführliche Dokumentation einer weiteren JEE Beispielapplikation mit REST-Webservices getriebenem Angular JS Frontend. Und hier noch eine weitere SPA (Single Page Appliction) Beispiel-Applikation, bei der das Testen des Backends mittels Arquillian und das integrative Testen des Frontends mittels Selenium (Workflow und UX Elemente) und QUnit  (Javascript-Framework zum Test-Aufruf der REST-Endpoints aus einer Browser-View) ebenfalls ausführlich beschrieben sind. Hier auch die passende Architekur-Bewertung zu den SPAs und REST-WebServices auf jaxenter.de.

Die Primefaces Beispiel-Applikation dieses Blog-Eintrags kann danach selbst erneut deployt werden, ohne den bereits gestarteten WildFly 10 Application Server überhaupt stoppen oder erneut starten zu müssen. Bei laufendem Server einfach ins Server-Unterverzeichnis /standalone/deployments

– eine leere Textdatei namens jobapplicationadmin-primefaces.war.dodeploy speichen und
– das Archiv jobapplicationadmin-primefaces.war aus dem jobapplicationadmin-primefaces/target-Verzeichnis speichern

Wie man sieht, macht es viel Freude, JEE-Applikationen mit der vorteilhaften Primefaces-Technologie zu entwickeln und ebenfalls, zuvor die Faces-Beispielapplikationen mittels JBoss Forge auf dem Datenmodell zu erzeugen und weiterzuentwickeln.

Es ist also sehr wahrscheinlich, dass noch weitere Blog-Einträge zu Webframeworks wie Primefaces, Angular JS und Faces und den die JEE-Spezifikation implementierenden Technologien folgen.

Allen interessierten Leserinnen und Lesern weiterhin viel Freude bei der agilen Softwareentwicklung mittels Scrum und dem Test Driven Development mit Java, sowie eine schöne, fröhliche und verantwortungsvolle Karnevals-Session.

WebApps – Primefaces 6, FileUploads, JSF 2, JPA 2, EJB 3, JEE7, REST, AngularJS, WildFly

Die Motivation

Über Beispiel-Applikationen zu der der sehr vorteilhaften Primefaces 6-Technologie gibt es bereits Blog-Einträge in diesem Blog hier. In diesem Blog-Eintrag soll nun nach dem zugrundeliegenden relationalen Datenmodell eine Primefaces 6 Beispiel-Webapplikation jobapplication-primefaces für eine MySQL 5 Datenbank erstellt werden. Dabei werden als Basis-Frontendtechnologien JSF 2 und Primefaces 6 verwendet. Weiterhin wird der Einsatz moderner Tag-Libs in den XHTML-Seiten der JEE7-Applikation erklärt.

Über die JSF Technologie in den Implementierungen RichFaces und Primefaces gibt es bereits mehrere Blog-Einträge in diesem Blog. In diesem Blog-Eintrag wird nun mittels JBoss Forge Eclipse PlugIn die Primefaces 6 Beispiel-Applikation jobapplication-primefaces auf dem Datenmodell mit den JPA 2 Entities erstellt unter Einsatz von JSF 2 und der robusten, elegant gestylten, etablierten, optimalen Primefaces Frontend-Technologie.

Die Beispiel-Applikation jobapplication-primefaces wird dann auf den JBoss WildFly 9 Final und JBoss WildFly 10 Final und JBoss WildFly 11 Final Application Servern deployt und getestet. Die Verwendung der JBoss WildFly JEE7-Application Server wurde in diesem Blog-Eintrag hier bereits einmal beschrieben. Dabei liefern die JEE6- und JEE7-Beispielapplikationen hier mit Hilfe eines EJB 3-getriebenen Backends (Session Beans als DAOs, DAO-Pattern) unter Anbindung der JPA 2 Entities (Table-Per-Class – Pattern) mit Hilfe von DTOs über fachliche RESTful ServiceInterfaces die benötigten Daten zur Präsentation und Bearbeitung (Änderung, Löschen, Neuanlage) in den Web-Frontends, welche die WebServices konsumieren (ServiceConsumer-Pattern). Der JPA-Provider ist dabei Hibernate von JBoss, welches auf dem WildFly zu konfigurieren ist. Hier auch das Entity-Relationship Diagramm:

E-R-diagram
(E-R-Diagramm der Beispiel-Datenbank „jobapplication“ ohne die MySQL-Sequence-Tabellen.)

Erstellung der Beispiel Applikation nach Datenmodell

Wie die Applikation jobapplication-primefaces mittels JBoss Forge erstellt werden kann, ist bereits analog in vorherigen Blog-Einträgen beschrieben worden, und wie in der pom.xml des jeweiligen Beispielprojekts nach erfolgtem Download erkennbar ist, wurden auch in der Applikation jobapplication-primefaces die folgenden JEE 7 Artefakte für den JBoss WildFly identifiziert, verwendet und importiert:

Maven JEE 7 JBoss-Artefakte und Maven Dependencies

WildFly JBoss Java EE 7 Specification APIs with Tools:
– jboss-javaee-7.0-with-tools
WildFly JBoss Java EE 7 Specification APIs with Resteasy:
– jboss-javaee-7.0-with-resteasy
WildFly JBoss Java EE 7 Specification APIs with Hibernate:
– jboss-javaee-7.0-with-hibernate

Weiterhin werden die folgenden JEE Dependencies (für das Servlet API, Annotationen, JAX-RS Implementierungen, JBoss RESTEasy, Jackson, Hibernate, JPA und EJB) verwendet:

– jboss-annotations-api_1.1_spec
– jboss-jaxrs-api_2.0_spec
– resteasy-jackson2-provider

– hibernate-jpa-2.1-api
– jboss-ejb-api_3.2_spec
– hibernate-jpamodelgen
– jboss-servlet-api_3.1_spec

Und ebenfalls die CDI 1.1 Dependency:

– cdi-api_1.1

Einsatz von CDI

Die Aktivierung von CDI erfolgt, wie beschrieben, mittels beans.xml im WEB-INF Verzeichnis der Beispielapplikation.

Auch über die Architektur und die verwendeten Design Patterns der Beispiel-Applikationen gibt es bereits Informationen in einem Blog-Eintrag hier und bereits vorausgegangenen Blog-Einträgen.

Primefaces 6:

Hat man erst einmal die JPA 2.2 Entities definiert und mittels JBoss Forge die Beispiel-Webapplikationen für die ausgewählte Frontend-Technologie (Angular JS oder Faces) erzeugt und rebrandet, ist die Migration der Faces Beispiel-Applikation leicht durchführbar und wurde bereits in den vorigen Blog-Einträgen beschrieben.

Die Einbindung der erforderlichen Primefaces-UI-Bibliothek primefaces-6.0.jar erfolgt dabei ganz simpel übers Hinzufügen der entsprechenden Maven Primefaces Dependency in der pom.xml.

<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>6.0</version>
</dependency>

Aktiviert werden die Primefaces-Tags in der gewünschten XHTML-Seite mittels folgendem Namespace Eintrag im Dokumenten-Kopf der XHTML-View xmlns:p=“http://primefaces.org/ui und die zusätzliche Funktionalität der JSTL-Tags wird entsprechend, wie in den MyFaces-Views auch, per xmlns:c=“http://java.sun.com/jsp/jstl/core verfügbar gemacht.

Durch die Verwendung von CDI 1.1 haben die JSF ManagedBeans stattdessen die Annotation @Named und bleiben ansonsten nahezu identisch zu den ManagedBeans der MyFaces-Applikationen. Weitere Informationen zu JSF 2.2, CDI und Primefaces finden sich auch hier im Blog von Balus C. Detail-Informationen zur JavaScript-Bibliothek jQuery, die vom Primefaces-Framework sehr intensiv verwendet wird, finden sich hier: jquery.org

forge.taglib.xml:

Die in den Beispiel-Applikationen verwendete, moderne Forge TagLib kann sehr einfach erweitert werden, indem die zusätzlich benötigten Methoden in der ViewUtils-Klasse ergänzt werden und deren Signaturen in der forge.taglib.xml im Verzeichnis src/main/webapp/WEB-INF/classes/META-INF/ bekanntgemacht werden, also genau wie bei klassischen TagLibs mit dem Unterschied, dass die verwendeten Tags innerhalb der Applikation in der ViewUtils-Klasse implementiert werden, was für die Applikation zusätzliche Sicherheit bringt. Diese Tags sind für jede Applikation sehr leicht adaptierbar und können genau auf die Applikation zugeschnitten werden. Die TagLib wird in der entsprechenden .xhtml-View über den Eintrag xmlns:forgeview=“http://jboss.org/forge/view“ mit dem Prefix forgeview unter der DOCTYPE-Definition im ui:composition eingebunden und mittels forgeview-Prefix per Expression Language (EL) an der gewünschten Stelle mit den richtigen Input-Parametern aufgerufen. Hier die forge.taglib.xml für die Beispiel-Applikation jobapplication-primefaces:

<?xml version=“1.0“ encoding=“UTF-8“?>
<!DOCTYPE facelet-taglib PUBLIC “-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN“ “http://java.sun.com/dtd/facelet-taglib_1_0.dtd“>
<facelet-taglib xmlns=“http://java.sun.com/JSF/Facelet“>
   <namespace>http://jboss.org/forge/view</namespace>
   <function>
       <function-name>asList</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             java.util.List asList(java.util.Collection)
       </function-signature>
   </function>
  
   <function>
       <function-name>display</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
           java.lang.String display(java.lang.Object)
       </function-signature>
   </function>
               
   <function>
       <function-name>count</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             int count(java.util.Collection)
       </function-signature>
   </function>
               
   <function>
       <function-name>displayShort</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayShort(java.lang.Object, int)
       </function-signature>
   </function>
               
   <function>
       <function-name>displayRange</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayRange(java.lang.Object,java.lang.Object)
       </function-signature>
   </function>

   <function>
       <function-name>displayFirst</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayFirst(java.lang.Object)
       </function-signature>
   </function>

   <function>
       <function-name>listExcludingSelectedOne</function-name>
       <function-class>de.binaris.jobapplication.view.ViewUtils</function-class>
       <function-signature>
             java.util.List listExcludingSelectedOne(java.util.Collection,java.lang.Object)
       </function-signature>
   </function>  
</facelet-taglib>

Hier auch die ViewUtils-Klasse unter Verwendung generischer Typen T und Collections List<T>:

ViewUtils:

package de.binaris.jobapplication.view;
 
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
 
import javax.persistence.Id;
 
/**
* Utilities for working with Java Server Faces views.
*/
public final class ViewUtils {
 
   public static <T> List<T> asList(Collection<T> collection) {
     if (collection == null) {
         return null;
     }
     return new ArrayList<T>(collection);
   }
 
   public static String display(Object object) {
     if (object == null) {
         return null;
     }
     try {
         // Invoke toString if declared in the class. If not found,
         // the NoSuchMethodException is caught and handled
         object.getClass().getDeclaredMethod(“toString“);
         return object.toString();
     }
     catch (NoSuchMethodException noMethodEx) {
         try {
           for (Field field : object.getClass().getDeclaredFields()) {
               // Find the primary key field and display it
               if (field.getAnnotation(Id.class) != null) {
                 // Find a matching getter and invoke it to display the key
                 for (Method method : object.getClass().getDeclaredMethods()) {
                     if (method.equals(new PropertyDescriptor(field.getName(),                    
                                         object.getClass()).getReadMethod()))
                     {
                       return method.invoke(object).toString();
                     }
                 }
               }
           }
           for (Method method : object.getClass().getDeclaredMethods()) {
               // Find the primary key as a property instead of a field, and display it
               if (method.getAnnotation(Id.class) != null) {
                 return method.invoke(object).toString();
               }
           }
         } catch (Exception ex) {
           // Unlikely, but abort and stop view generation if any exception is thrown
           throw new RuntimeException(ex);
         }
     }
     return null;
   }
 
   public static <T> int count(Collection<T> collection) {
     if (collection == null) {
               return 0;
     }
     return collection.size();
   }
 
   public static String displayRange(Object object1, Object object2) {
     String text1 = display(object1);
     String text2 = display(object2);
      if (text1 == null || text2 == null
          || text1.trim() == null || text2.trim() == null) {
           return null;
      }
     return (text1 + “-“ + text2);
   }
               
   public static String displayFirst(Object object) {
     String text = display(object);
      if (text == null || text.split(“\\s+“) == null
          || text.split(“\\s+“)[0] == null) {
           return null;
      }
     return (text.split(“\\s+“)[0] + “…“);
   }
 
   public static String displayShort(Object object, int length) {
     String text = display(object);
      if (text == null || text.split(“[‚.‘]“) == null
           || text.split(“[‚.‘]“)[0] == null) {
           return null;
      }
     String[] elements = text.split(“[‚.‘]“);
     String result = ““;
      if (text.length() < length) {
         return text;
      } else {
         result = text.substring(0,length-4) + „…“;
         return result;
      }
   }

   public static <T> List<T> listExcludingSelectedOne(Collection<T> collection, T selected) {
     if (collection == null) {
         return null;
     }
     if (selected == null) {
       return new ArrayList<T>(collection);
     }
     List<T> list = new ArrayList<T>(collection);
     list.remove(selected);
     return list;
   }
 
   private ViewUtils() {
     // Can never be called, only by getInstance – Singleton pattern
   }

   public static ViewUtils getInstance() {
      return new ViewUtils();
   }
}

Über Tags, TagLibs und die Erweiterung bestehender und die Definition eigener Tags wird es noch einen Blog-Eintrag hier in diesem Blog geben und durch die soeben gezeigten Beispiele ist erkennbar, wie simpel es ist, eigene Tags für die .xhtml-Views heutiger JSF 2-Applikationen zu definieren und deren Utility functions-Signaturen im WEB-INF/classes/META-INF-Verzeichnis des classpaths als *name*-taglib.xml mit dem folgenden XML Document-Header und dem jboss-forge-view namespace zu deklarieren (s.o. forge.taglib.xml).

Alle XML und XHTML-Dateien der Primefaces-Beispielapplikation finden sich im Deployment-Archiv jobapplication-primefaces.war im /target-Unterverzeichnissen des Projekts jobapplication-primefaces.

Als zusätzliche Abhängigkeiten für den FileUpload wurden ebenfalls die im Primefaces Users Guide genannten folgenden optionalen Apache Bibliotheken (commons) hinzugefügt:

commons-fileupload 1.3
commons-io 2.2

Um optional einen FileUploadFilter zu aktivieren, wurden zusätzlich zu seiner Deklaration in der web.xml auch die Methoden doFilter(…) und init(FilterConfig) überschrieben. Hier die web.xml:

<?xml version=“1.0″ encoding=“UTF-8″ standalone=“no“?>
<web-app xmlns=“http://java.sun.com/xml/ns/javaee“ xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“ version=“3.0″ xsi:schemaLocation=“http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd“>
  <display-name>HR Job Application</display-name>
  <filter>
    <filter-name>FileUploadFilter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    <init-param>
       <param-name>thresholdSize</param-name>
       <param-value>8000000</param-value>
    </init-param>
    <init-param>
       <param-name>uploadDirectory</param-name>
       <param-value>/Temp</param-value>
    </init-param>
  </filter>
  <session-config>
      <session-timeout>30</session-timeout>
  </session-config>
  <servlet>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
  <error-page>
    <error-code>404</error-code>
    <location>/faces/error.xhtml</location>
  </error-page>
  <error-page>
    <error-code>500</error-code>
    <location>/faces/error.xhtml</location>
  </error-page>
  <context-param>
    <param-name>

  javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE

</param-name>
    <param-value>true</param-value>
  </context-param>
</web-app>

Ein Hinweis zur web.xml und dem Parameter threshold. Wenn der Upload-Inhalt größer als der angegebene threshold ist, wird die Datei automatisch im genannten Upload-Verzeichnis gespeichert, weshalb hier ein entsprechend großer Wert zu wählen ist.

Noch ein Hinweis zur Speicherung der hochgeladenen PDF- oder Bild-Dateien in der MySQL. Wenn man beim Klick auf die “Step 3 Speichern“-Schaltfläche und der anschließenden Ausführung der update()-Methode der FileUploadBean-EJB den folgenden LogFile-Eintrag über eine com.mysql.jdbc.PacketTooBigException bekommt, kann in der MySQL-Konfigurationsdatei das Attribut max_allowed_packet = 16M gesetzt werden. Danach ist die MySQL-Datenbank neu zu starten, oder man setzt das Attibut nur temporär über die Kommandozeile: mysql> SET GLOBAL max_allowed_packet=16M. Dabei ist das Limit für max_allowed_packet 1GB, was einer Deklaration von max_allowed_packet=1G entspricht. Danach wird die FileUpload-Entity auch in der file_upload InnoDb-Tabelle der MySQL-Datenbank jobapplication gespeichert.

Die Primefaces Beispiel-Applikation arbeitet über die RESTful WebService-Schnittstelle auf der MySQL-InnoDB. Für die Primefaces Beispiel-Applikationen kann das mit HeidiSQL erstellte MySQL 5.x Datenbank-Skript verwendet werden.

WildFly Anbindung an MySQL5 und deklarative WildFly 11 Hibernate-Konfiguration

Die Konfiguration des JBoss WildFly Application Servers 11 Final erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2, 9 und 10 Final und betrifft die Datasource, die MySQL-Datenbank Inno DB 5.x, Hibernate 5, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle ein wichtiges Thema, welches noch genauer beschrieben werden wird. Die Anbindung an die relationale  Datenbank MySQL 5 erfolgt übrigens analog für die JBoss Application Server WildFly 8.1, 8.2, 9, 10 und WildFly 11.

Je nach verwendeter Datenbank kann in der persistence.xml im Deployment-Paket der Beispiel-App jobapplication-primefaces.war ein entsprechender Datenbank-Dialekt eingetragen werden:

Hier die /META-INF/persistence.xml der Beispiel-Applikation für MySQL5:

    <xml version=“1.0″ encoding=“UTF-8″?>
    <persistence version=“2.0″ xmlns=“http://java.sun.com/xml/ns/persistence“
    xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
    xsi:schemaLocation=“http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd“>
    <persistence-unit name=“JobapplicationPU“>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>
            java:jboss/datasources/JobapplicationDatasource
    </jta-data-source>
    <properties>
    <property name=“hibernate.hbm2ddl.auto“ value=“none“/>
    <property name=“hibernate.show_sql“ value=“false“/>
    </properties>
    </persistence-unit>
    </persistence>

Dafür wird je Datenbank die folgende Datasource benötigt und ist in der standalone/configuration/standalone.xml des JBoss WildFly Servers unter den <datasources> einzutragen:

Für MySQL 5:

    <datasource jndi-name=“java:jboss/datasources/JobapplicationDatasource“ pool-name=“JobapplicationDS“ enabled=“true“>
<connection-url>jdbc:mysql://localhost:3306/jobapplication</connection-url>

    <driver>mysql-connector-java-5.1.34.jar</driver>
    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
    <pool>
    <min-pool-size>10</min-pool-size>
    <max-pool-size>100</max-pool-size>
    <prefill>true</prefill>
    </pool>
    <security>
    <user-name>root</user-name>
    <password>das entsprechende Passwort</password>
    </security>
    <statement>
    <prepared-statement-cache-size>32</prepared-statement-cache-size>
    <share-prepared-statements>true</share-prepared-statements>
    </statement>
    </datasource>

Für die erfolgreiche Anbindung der soeben deklarierten Datasoures werden die Datenbank-Treiber auf Modul-Ebene des JBoss WildFly konfiguriert, wie noch genauer beschrieben wird.

Damit die Datasources die soeben konfigurierten Treiber auch finden, werden diese in der /standalone/configuration/standalone.xml bei den <datasources>deklariert:

Für MySQL 5:

<driver name=“mysql-connector-java-5.1.34.jar“ module=“com.mysql“>
   <driver-class>com.mysql.jdbc.Driver</driver-class>
   <xa-datasource-class>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource
   </xa-datasource-class>
</driver>

Die Hibernate-Konfiguration des WildFly 11 Final Servers ist ebenfalls leicht durchführbar. Hierfür werden im WildFly11 Server-Verzeichnis wildfly-11.0.0.Final/modules/system/layers/base/org/hibernate/main folgende Dateien hinterlegt:

– hibernate-core-5.1.10.Final.jar
– hibernate-entitymanager-5.1.10.Final.jar
– hibernate-envers-5.1.10.Final.jar
– hibernate-java8-5.1.10.Final.jar
– jipijapa-hibernate5-11.0.0.Final.jar
– module.xml
– mysql-connector-java-5.1.34.jar
– mysql-connector-java-5.1.34.jar.index

Die fertige Beispiel-Applikation jobapplication-primefaces kann leicht selbst deployt werden und wird diesmal nicht auf dem Test-Server deployt, um den Eindruck zu vermeiden, man könnte sich darüber real bewerben. Aus demselben Grund wurden in der Beispiel-Applikation auch das Firmen-Logo durch ein neutrales Emblem ersetzt und ebenfalls der Link auf binaris.de entfernt. Denn bei Binaris Informatik bewirbt man sich nach wie vor am besten hier.

Bei dieser Gelegenheit darf auch das sehr effektive, interessante und erfolgreiche Seminar

“TDD mit Java”

hier von Binaris Informatik ebenfalls positiv erwähnt werden.

Hier die Beispiel-Projekte für die Entwicklungsumgebungen JBoss Developer Studio und intelliJ 15:

JBoss Developer Studio Projekt:

jobapplication-primefaces

intelliJ Projekt:

jobapplication-primefaces

Hier der WildFly 9 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 7.

Hier der WildFly 10 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank für den WildFly 9 und den WildFly 10 gibt es hier mehr Informationen in diesem Blog.

Die fertig konfigurierte Version des WildFly 10.0.0.Final mit vielen Beispiel-Applikationen der vorigen Blog-Einträge hier zum Download bereit, kann runtergeladen, entpackt und gestartet werden. Dabei ist nur der Pfad für JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 8 – Verzeichnis des Server-Systems zeigt.

Hier auch der WildFly 11 als Zip-Archiv zum Download und Entpacken, für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank wird ebenfalls auf bereits vorhandene Blog-Einträge hier verwiesen, da die Konfigurationen analog zum WildFly 9 und WildFly 10 durchzuführen sind.

Der fertig konfigurierte WildFly 11 mit vielen Beispiel-Applikationen der vorangegangenen Blog-Einträge ist hier zum Download verfügbar, kann runtergeladen, entpackt und gestartet werden. Auch hier ist nur der Pfad des JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 9 – Verzeichnis des Server-Systems zeigt.

Mehr Informationen zum Java 9 Release gibt es hier:

https://www.technotification.com/2017/09/java-9-is-finally-released.html

Herunterladen kann man sich das Java 9 für die gewünschte Betriebssystem-Plattform hier:

http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html

In Fällen mit Migrations-Bedarf gibt es hier weitere Informationen.

Hier die Release-Notes zu Java 9:

http://www.oracle.com/technetwork/java/javase/9-relnotes-3622618.html

Oracle Support für das Oracle JDK 8:
Nach January 2019 läuft nun der Oracle Support für das Oracle JDK 8 aus, weshalb es dann keine Updates mehr für Java SE 8 geben wird. Weiterhin wird ein entsprechender Oracle Support Vertrag für die produktive Verwendung der Java Versionen 6, 7, 9, 10 und 11 erforderlich werden. Mehr information gibt es in diesem Blog hier.

Oracle Java wird also ab Februar 2019 produktiv nicht mehr gebührenfrei einsetzbar sein, weshalb es von RedHat frei einsetzbare OpenJDK Java Versionen gibt, welche von RedHat auch für Endanwender und Unternehmen kostenfrei supportet werden. Hierfür ist lediglich eine Red Hat Enterprise Linux oder Middleware Subscription erforderlich.

Die SQL-Skripte zum Anlegen und Befüllen der MySQL Beispiel-Datenbanken finden sich verlinkt in den Blog-Einträgen wieder, die hier durchsucht werden können, durch Eingabe eines Stichworts des Titels oder Blog-Eintrag Texts im Feld Suche… der Eingabemaske.

Hier auch nochmal die ausführliche Dokumentation einer weiteren JEE Beispielapplikation mit REST-Webservices getriebenem Angular JS Frontend. Und hier noch eine weitere SPA (Single Page Appliction) Beispiel-Applikation, bei der das Testen des Backends mittels Arquillian und das integrative Testen des Frontends mittels Selenium (Workflow und UX Elemente) und QUnit  (Javascript-Framework zum Test-Aufruf der REST-Endpoints aus einer Browser-View) ebenfalls ausführlich beschrieben ist.

Die Primefaces Beispiel-Applikation dieses Blog-Eintrags kann danach selbst erneut deployt werden, ohne den bereits gestarteten WildFly 10 Application Server überhaupt stoppen oder erneut starten zu müssen. Bei laufendem Server einfach ins Server-Unterverzeichnis /standalone/deployments

– das Archiv jobapplication-primefaces.war aus dem jobapplication-primefaces/target-Verzeichnis speichern

Ein Hinweis zum FileUpload mit Angular JS: Der FileUpload geht, z. B. gecroppt, ebenfalls mit Angular JS, was auch in einem der nächsten Blog-Einträge thematisiert werden wird. Hier schonmal ein Croppie-Beispiel (Basis-Projekt) unter Verwendung von zusätzlichen angularjs und file-upload Javascript-Dateien, welches gerne ausgebaut werden kann.

Wie man sieht, macht es viel Freude, JEE-Applikationen mit der vorteilhaften Primefaces-Technologie zu entwickeln und ebenfalls, zuvor die Faces-Beispielapplikationen mittels JBoss Forge auf dem Datenmodell zu erzeugen und weiterzuentwickeln.

Es ist also sehr wahrscheinlich, dass noch weitere Blog-Einträge zu Webframeworks wie Primefaces, Angular JS und Faces und den die JEE-Spezifikation implementierenden Technologien folgen.

Allen interessierten Leserinnen und Lesern weiterhin viel Freude bei der agilen Softwareentwicklung mittels Scrum und dem Test Driven Development mit Java, sowie eine schöne, fröhliche und verantwortungsvolle Karnevals-Session und einen unterhaltsamen Super Bowl mit seinen legendären Halbzeitauftritten.

WebApps – Responsiv mit Angular JS, REST, JEE7, Java 8 auf JBoss WildFly 9 und 10

Die Motivation

Im Blog-Eintrag über WebApps – vom Modell zur App, mit JSF 2.2, Angular JS, REST, JPA 2 hier wurde beschrieben, wie leicht es ist, von einem Klassen-Diagramm (UML), genauer: Entity-Relationship-Diagramm (E-R Diagramm), zu einer JEE7-Applikation zu kommen. Diese JEE6- und JEE7-Beispielapplikationen hier liefern mit Hilfe eines EJB 3-getriebenen Backends (Session Beans als DAOs, „DAO“-Pattern) unter Anbindung der JPA 2 Entities („Table-Per-Class“-Pattern) mit Hilfe von DTOs über fachliche RESTful ServiceInterfaces oder Microservice (Docker, Spring Boot), siehe auch „ServiceBroker“-Pattern hier, die benötigten Daten zur Präsentation und Bearbeitung (Änderung, Löschen, Neuanlage) in den Web-Frontends, welche die WebServices konsumieren („ServiceConsumer“-Pattern).

E-R-diagram
(E-R-Diagramm der Beispiel-Datenbank „logisticsadmin“ ohne die MySQL-Sequence-Tabellen.)

Die Beispiel-Applikation logisticsadmin-angularjs wird dann auf den JBoss WildFly 9 Final, den JBoss WildFly 10 Final und den JBoss WildFly 11 Final Application Servern deployt und getestet. Die Verwendung der JBoss WildFly JEE7-Application Server wurde in diesem Blog-Eintrag bereits einmal beschrieben. Dabei  liefern die JEE6- und JEE7-Beispielapplikationen hier mit Hilfe eines EJB 3-getriebenen Backends (Session  Beans als DAOs, DAO-Pattern) unter Anbindung der JPA 2 Entities (Table-Per-Class – Pattern) mit Hilfe von  DTOs über fachliche RESTful ServiceInterfaces die benötigten Daten zur Präsentation und Bearbeitung  (Änderung, Löschen, Neuanlage) in den Web-Frontends, welche die WebServices konsumieren  (ServiceConsumer-Pattern). Der JPA-Provider ist hier Hibernate von JBoss, wofür WildFly 9, 10 und 11 zu  konfigurieren sind. Das Durchsuchen, und die Nutzung einer Pagination der Ergebnisliste ist ebenfalls in der Beispiel-App enthalten, wie auch mit Hilfe des Angular JS Frameworks und des Bootstrap-Frameworks eine dynamische Benutzeroberfläche, die sich an beliebige Auflösungen und Display-Größen responsiv anpasst. Dabei darf positiv erwähnt werden, dass man mittels JBoss Forge eine saubere, stringente Architektur in die JEE7-Applikation einbringt, die beim Weiterentwickeln der App sehr hilfreich ist und sowohl die Entwicklungszeit-Performance als auch die Codequalität deutlich steigert. Danke, JBoss Rockstars!

jQuery oder Angular JS

Die oft hierüber geführte Diskussion ist inzwischen eigentlich obsolet geworden, da es meiner Erfahrung nach eher unproblematisch ist, beide JavaScript-Frameworks in derselben Browser-Applikation zu verwenden und solange man nicht versucht, beide Frameworks auf ein und demselben HTML-Element anzuwenden, kommen diese sich auch weder bei der Event-Triggerung noch beim Event-Handling in die Quere. Hier ist ein funktionierendes Beispiel dazu mit einem jQuery-Accordion und jQuery-Caroussel auf der Startseite und zusätzlich einer verlinkten Angular JS Such-Applikation im Events Header-Menü.

Erstellung der Beispiel Applikation aus dem Datenmodell

Mittels Eclipse-PlugIn Umlet wird das Klassendiagramm der Entities und Datenbank-Objekte erstellt und aus diesem, nach dem Anlegen der Datenbank logisticsadmin per Hibernate Envers während dem WildFly 10 Undertow Deployment mittels JBoss Forge PlugIn im JBoss Developer Studio erst der REST-WebService mit den Endpoints generiert und danach die Angular JS WebApp auf diesem RESTful WebService.

Maven JEE 7 JBoss-Artefakte und Maven Dependencies

Dabei werden in der pom.xml die folgenden Maven Dependencies verwendet und es soll nicht vergessen werden, dass die heute in Java 8 enthaltenen javax.ws.rs  REST-Packages ohne die bereits vor vielen Jahren erfolgte sehr gute Vorarbeit der Entwickler des jboss-resteasy REST-Frameworks wohl in der heutigen Form noch nicht im JDK vorhanden wären. Nochmals Danke, JBoss Rockstars!

WildFly JBoss Java EE 7 Specification APIs with Tools:
– jboss-javaee-7.0-with-tools
WildFly JBoss Java EE 7 Specification APIs with Resteasy:
– jboss-javaee-7.0-with-resteasy
WildFly JBoss Java EE 7 Specification APIs with Hibernate:
– jboss-javaee-7.0-with-hibernate

Weiterhin werden die folgenden JEE Dependencies (für das Servlet API, Annotationen, JAX-RS Implementierungen, JBoss RESTEasy, Jackson, Hibernate, JPA und EJB) verwendet:

– jboss-annotations-api_1.1_spec
– jboss-jaxrs-api_2.0_spec
– resteasy-jackson2-provider

– hibernate-jpa-2.1-api
– jboss-ejb-api_3.2_spec
– hibernate-jpamodelgen
– jboss-servlet-api_3.1_spec

 Einsatz von CDI

Und ebenfalls die CDI 1.1 Dependency:

– cdi-api_1.1

Die Aktivierung von CDI erfolgt, wie beschrieben, mittels beans.xml im WEB-INF Verzeichnis.

Auch über die Architektur und die verwendeten Design Patterns der Beispiel-Applikationen gibt es bereits Informationen in einem Blog-Eintrag hier und bereits vorausgegangenen Blog-Einträgen.

Konfiguration des JBoss WildFly 10 Application Servers

Die Konfiguration des JBoss WildFly Application Servers 10 Final erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2 und 9 Final und betrifft die Datasource, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle, sowie die Konfiguration der MySQL-Datenbank Inno DB in vorigen Blog-Einträgen bereits beschrieben worden.

Bei dieser Gelegenheit darf auch das sehr effektive, interessante und erfolgreiche Seminar

“TDD mit Java” von Binaris Informatik ebenfalls positiv erwähnt werden.

Hier auch die /META-INF/persistence.xml der Beispiel-Applikation:

    <xml version=“1.0″ encoding=“UTF-8″?>
    <persistence version=“2.0″ xmlns=“http://java.sun.com/xml/ns/persistence“
    xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
    xsi:schemaLocation=“http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd“>
    <persistence-unit name=“LogisticsadminPU“>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>
    java:jboss/datasources/LogisticsadminDatasource
    </jta-data-source>
    <properties>
    <property name=“hibernate.hbm2ddl.auto“ value=“none“/>
    <property name=“hibernate.show_sql“ value=“false“/>
    </properties>
    </persistence-unit>
    </persistence>

Dafür wird die folgende Datasource benötigt und ist in der standalone/configuration/standalone.xml des JBoss WildFly Servers unter den <datasources> einzutragen:

    <datasource jndi-name=“java:jboss/datasources/LogisticsadminDatasource“ pool-name=“LogisticsadminDS“
    enabled=“true“>
    <connection-url>jdbc:mysql://localhost:3306/logisticsadmin</connection-url>
    <driver>mysql-connector-java-5.1.34.jar</driver>
    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
    <pool>
    <min-pool-size>10</min-pool-size>
    <max-pool-size>100</max-pool-size>
    <prefill>true</prefill>
    </pool>
    <security>
    <user-name>root</user-name>
    <password>das entsprechende Passwort</password>
    </security>
    <statement>
    <prepared-statement-cache-size>32</prepared-statement-cache-size>
    <share-prepared-statements>true</share-prepared-statements>
    </statement>
    </datasource>

Die fertige Beispiel-Applikation logisticsadmin-angularjs kann zusammen mit den anderen Beispiel-Applikationen hier betrachtet werden.

Hier das Beispiel-Projekte für die Eclipse-Entwicklungsumgebung JBoss Developer Studio:

logisticsadmin-angularjs

Hier der WildFly 10 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank für den WildFly 9 und den WildFly 10 gibt es hier mehr Informationen in diesem Blog.

Die fertig konfigurierte Version des WildFly 10.0.0.Final mit vielen Beispiel-Applikationen der vorigen Blog-Einträge hier zum Download bereit, kann runtergeladen, entpackt und gestartet werden. Dabei ist nur der Pfad für JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 8 – Verzeichnis des Server-Systems zeigt.

Hier auch der WildFly 11 als Zip-Archiv zum Download und Entpacken, für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank wird ebenfalls auf bereits vorhandene Blog-Einträge hier verwiesen, da die Konfigurationen analog zum WildFly 9 und WildFly 10 durchzuführen sind.

Der fertig konfigurierte WildFly 11 mit vielen Beispiel-Applikationen der vorangegangenen Blog-Einträge ist hier zum Download verfügbar, kann runtergeladen, entpackt und gestartet werden. Auch hier ist nur der Pfad des JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 9 – Verzeichnis des Server-Systems zeigt.

Mehr Informationen zum kürzlichen erschienenen Java 9 Release gibt es hier:

https://www.technotification.com/2017/09/java-9-is-finally-released.html

Herunterladen kann man sich das Java 9 für die gewünschte Betriebssystem-Plattform hier:

http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html

In Fällen mit Migrations-Bedarf gibt es hier weitere Informationen.

Hier die Release-Notes zu Java 9:

http://www.oracle.com/technetwork/java/javase/9-relnotes-3622618.html

Die SQL-Skripte zum Anlegen und Befüllen der MySQL Beispiel-Datenbanken finden sich verlinkt in den Blog-Einträgen wieder, die hier durchsucht werden können, durch Eingabe eines Stichworts des Titels oder Blog-Eintrag Texts im Feld Suche… der Eingabemaske.

Hier auch nochmal die ausführliche Dokumentation einer weiteren JEE Beispielapplikation mit REST-Webservices getriebenem Angular JS Frontend. Und hier noch eine weitere SPA (Single Page Appliction) Beispiel-Applikation, bei der das Testen des Backends mittels Arquillian und das integrative Testen des Frontends mittels Selenium (Workflow und UX Elemente) und QUnit  (Javascript-Framework zum Test-Aufruf der REST-Endpoints aus einer Browser-View) ebenfalls ausführlich beschrieben ist.

Die Angular JS Beispiel-Applikation dieses Blog-Eintrags kann auch selbst erneut deployt werden, ohne den bereits gestarteten WildFly Application Server überhaupt stoppen oder erneut starten zu müssen. Bei laufendem Server einfach ins Server-Unterverzeichnis /standalone/deployments

– eine leere Textdatei namens logisticsadmin-angularjs.war.dodeploy speichen und
– das Archiv logisticsadmin-angularjs.war aus dem logisticsadmin-angularjs/target-Verzeichnis speichern

Sofort wird die Beispiel-Applikation deployt und in wenigen Sekunden gestartet und kann aufgerufen werden:

http://localhost:8080/logisticsadmin-angularjs

Wie man sieht, macht es einfach Spaß, die responsiven Angular JS-Beispielapplikationen mittels JBoss Forge auf dem Datenmodell zu erzeugen und weiterzuentwickeln.

Es ist also sehr wahrscheinlich, dass noch weitere Blog-Einträge zu Webframeworks wie Primefaces, Angular JS und Faces und den die JEE-Spezifikation implementierenden Technologien folgen.

Allen interessierten Leserinnen und Lesern weiterhin viel Freude bei der agilen Softwareentwicklung mittels Scrum und dem Test Driven Development mit Java, sowie eine besinnliche Weihnachtszeit und viel Freude beim Weihnachtsfeiern, ebenso wie einen angenehmen Jahreswechsel in ein neues, erfolgreiches Jahr 2019.

WebApps – RESTful mit JSF 2, JPA 2, EJB 3, Primefaces 6, JEE7, Java 8 und 9 auf WildFly 9, 10 und 11

Die Motivation

In diesem Blog-Eintrag soll nach einem zugrundeliegenden relationalen Datenmodell eine Primefaces 6 Beispiel-Webapplikation businessdinners-primefaces für eine MySQL 5 Datenbank Datenbank erstellt werden. Über Beispiel-Applikationen zu der sehr vorteilhaften Primefaces 6-Technologie gibt es bereits Blog-Einträge in diesem Blog hier. Dabei wird als Basis-Frontendtechnologie JSF 2 in der Primefaces 6-Implementierung auf dem WildFly 9, 10 und 11 verwendet. Weiterhin wird der Einsatz moderner Tag-Libs in den XHTML-Seiten der JEE7-Applikation erklärt.

Mittels JBoss Forge Eclipse PlugIn wird die Primefaces 6 Beispiel-Applikation businessdinners-primefaces auf dem Datenmodell mit den JPA 2 Entities erstellt unter Einsatz von JSF 2 und der robusten, elegant gestylten, etablierten, optimalen Primefaces Frontend-Technologie.

Die Beispiel-Applikation businessdinners-primefaces wird dann auf den JBoss WildFly 9 Final, dem JBoss WildFly 10 Final und dem neuen JBoss WildFly 11 Final Application Servern deployt und getestet. Die Verwendung der JBoss WildFly JEE7-Application Server wurde in diesem Blog-Eintrag hier bereits einmal beschrieben. Dabei  liefern die JEE6- und JEE7-Beispielapplikationen hier mit Hilfe eines EJB 3-getriebenen Backends (Session  Beans als DAOs, DAO-Pattern) unter Anbindung der JPA 2 Entities (Table-Per-Class – Pattern) mit Hilfe von  DTOs über fachliche RESTful ServiceInterfaces die benötigten Daten zur Präsentation und Bearbeitung  (Änderung, Löschen, Neuanlage) in den Web-Frontends, welche die WebServices konsumieren  (ServiceConsumer-Pattern). Der JPA-Provider ist hier Hibernate von JBoss, wofür WildFly 9, 10 und 11 zu  konfigurieren sind. Mittels Criteria-API werden aus dem Backend die benötigten Daten für das Frontend gelesen, welche in der jeweiligen Geschäftsessen-Teilnehmerorganisations-Applikation (“Businessdinners“) dann auswählbar sind.

Erstellung der Beispiel Applikation nach Datenmodell

Wie die Applikation businessdinners-primefaces mittels JBoss Forge erstellt werden kann, ist bereits in vorigen Blog-Einträgen für die JEE-Applikationen beschrieben worden und wie daraus die Businessdinners-Applikation weiterentwickelt werden kann. Hier das mittels DBeaver erstellte Entity-Relationship Diagramm der businessdinners-primefaces – MySQL Datenbank mit dem zugrundeliegenden Datenmodell:

E-R-diagram
(E-R-Diagramm der Beispiel-Datenbank „businessdinners“ ohne die MySQL-Sequence-Tabellen.)

(Anm.: Die Tabelle User, welche die Gäste des Business Dinners darstellt, enthält dabei die Adresse, welche eingebettet in die Tabelle integriert ist und deshalb auf der Entity „User“ als @Embeddable Adresse annotiert wird. Ebenso die Tabelle Venue.)

Dabei darf positiv erwähnt werden, dass man mittels JBoss Forge eine saubere, stringente Architektur in die JEE7-Applikation einbringt, die beim Weiterentwickeln der App sehr hilfreich ist und sowohl die Entwicklungszeit-Performance als auch die Codequalität deutlich steigert. Danke, JBoss Rockstars!

In der pom.xml des jeweiligen Beispielprojekts nach erfolgtem Download erkennbar, wurden in der Applikation businessdinners-primefaces ebenfalls die folgenden JEE 7 Artefakte für den JBoss WildFly identifiziert, verwendet und importiert:

Maven JEE 7 JBoss-Artefakte und Maven Dependencies

WildFly JBoss Java EE 7 Specification APIs with Tools:
– jboss-javaee-7.0-with-tools
WildFly JBoss Java EE 7 Specification APIs with Resteasy:
– jboss-javaee-7.0-with-resteasy
WildFly JBoss Java EE 7 Specification APIs with Hibernate:
– jboss-javaee-7.0-with-hibernate

Weiterhin werden die folgenden JEE Dependencies verwendet für das Servlet API, Annotationen, JAX-RS Implementierungen, JBoss RESTEasy und der RESTEasy Jackson Provider, Hibernate, JPA 2.1 und EJB 3.2:

– jboss-annotations-api_1.1_spec
– jboss-jaxrs-api_2.0_spec
– resteasy-jackson2-provider

– hibernate-jpa-2.1-api
– jboss-ejb-api_3.2_spec
– hibernate-jpamodelgen
– jboss-servlet-api_3.1_spec

 Einsatz von CDI

Und ebenfalls die CDI 1.1 Dependency:

– cdi-api_1.1

Die Aktivierung von CDI erfolgt, wie beschrieben, mittels beans.xml im WEB-INF Verzeichnis.

Auch über die Architektur und die verwendeten Design Patterns der Beispiel-Applikationen gibt es bereits Informationen in einem Blog-Eintrag hier und bereits vorausgegangenen Blog-Einträgen.

Primefaces 6:

Hat man erst einmal die JPA 2.1 Entities definiert und mittels JBoss Forge die Beispiel-Webapplikationen für die ausgewählte Frontend-Technologie (Angular JS oder Faces) erzeugt und rebrandet, ist die Migration der Faces Beispiel-Applikation auf Primefaces leicht durchführbar und wurde bereits in den vorigen Blog-Einträgen beschrieben.

Die Einbindung der erforderlichen Primefaces-UI-Bibliothek primefaces-6.1.jar erfolgt dabei ganz simpel übers Hinzufügen der entsprechenden Maven Primefaces Dependency in der pom.xml.

<dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>6.1</version>
</dependency>

Durch Änderung dieses Eintrags in der pom.xml kann auf die gewünschte Primefaces-Version umgestellt werden, z.B. auf die Primefaces 6.2.RC1 Bibliothek, die seit Januar 2018 verfügbar ist. Bei der Ausprogrammierung der XHTML-Views auf Primefaces sind der Primefaces Showcase und der neue Primefaces 6.1 Users Guide (PDF) sehr hilfreich. Der größte Aufwand der Migration besteht hierbei im Austausch der Standard MyFaces-Tags (h: Präfix) durch die Primefaces-Tags (p: Präfix) ist also für die simplen Beispiel-Applikationen leicht umsetzbar. Ebenfalls wurde das sehr gute bei DZone erhältliche PDF zur JSTL (Java Server Pages Template Library) verwendet.

Aktiviert werden die Primefaces-Tags in der gewünschten XHTML-Seite mittels folgendem Namespace Eintrag im Dokumenten-Kopf der XHTML-View xmlns:p=“http://primefaces.org/ui und die zusätzliche Funktionalität der JSTL-Tags wird entsprechend, wie in den MyFaces-Views auch, per xmlns:c=“http://java.sun.com/jsp/jstl/core verfügbar gemacht.

Durch die Verwendung von CDI 1.1 haben die JSF ManagedBeans stattdessen die Annotation @Named und bleiben ansonsten nahezu identisch zu den ManagedBeans der MyFaces-Applikationen. Weitere Informationen zu JSF 2, CDI und Primefaces finden sich auch hier im Blog von Balus C. Detail-Informationen zur JavaScript-Bibliothek jQuery, die vom Primefaces-Framework sehr intensiv verwendet wird, finden sich hier: jquery.org

forge.taglib.xml:

Die in den Beispiel-Applikationen verwendete, moderne Forge TagLib kann sehr einfach erweitert werden, indem die zusätzlich benötigten Methoden in der ViewUtils-Klasse ergänzt werden und deren Signaturen in der forge.taglib.xml im Verzeichnis src/main/webapp/WEB-INF/classes/META-INF/ bekanntgemacht werden, also genau wie bei klassischen TagLibs mit dem Unterschied, dass die verwendeten Tags innerhalb der Applikation in der ViewUtils-Klasse implementiert werden, was für die Applikation zusätzliche Sicherheit bringt, anstatt in einer extra TagLib. Diese Tags sind für jede Applikation sehr leicht adaptierbar und können genau auf die Applikation zugeschnitten werden. Die TagLib wird in der entsprechenden .xhtml-View über den Eintrag xmlns:forgeview=“http://jboss.org/forge/view“ mit dem Prefix forgeview unter der DOCTYPE-Definition im ui:composition eingebunden und mittels forgeview-Prefix per Expression Language (EL) an der gewünschten Stelle mit den richtigen Input-Parametern aufgerufen. Hier die forge.taglib.xml für die Beispiel-Applikation businessdinners-primefaces:

<?xml version=“1.0“ encoding=“UTF-8“?>
<!DOCTYPE facelet-taglib PUBLIC “-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN“ “http://java.sun.com/dtd/facelet-taglib_1_0.dtd“>
<facelet-taglib xmlns=“http://java.sun.com/JSF/Facelet“>
   <namespace>http://jboss.org/forge/view</namespace>
   <function>
       <function-name>asList</function-name>
       <function-class>de.binaris.businessdinners.view.ViewUtils</function-class>
       <function-signature>
             java.util.List asList(java.util.Collection)
       </function-signature>
   </function>
   
   <function>
       <function-name>display</function-name>
       <function-class>de.binaris.businessdinners.view.ViewUtils</function-class>
       <function-signature>
           java.lang.String display(java.lang.Object)
       </function-signature>
   </function>
                
   <function>
       <function-name>count</function-name>
       <function-class>de.binaris.businessdinners.view.ViewUtils</function-class>
       <function-signature>
             int count(java.util.Collection)
       </function-signature>
   </function>
                
   <function>
       <function-name>displayShort</function-name>
       <function-class>de.binaris.businessdinners.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayShort(java.lang.Object, int)
       </function-signature>
   </function>
                
   <function>
       <function-name>displayRange</function-name>
       <function-class>de.binaris.businessdinners.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayRange(java.lang.Object,java.lang.Object)
       </function-signature>
   </function>

   <function>
       <function-name>displayFirst</function-name>
       <function-class>de.binaris.businessdinners.view.ViewUtils</function-class>
       <function-signature>
             java.lang.String displayFirst(java.lang.Object)
       </function-signature>
   </function>

   <function>
       <function-name>listExcludingSelectedOne</function-name>
       <function-class>de.binaris.businessdinners.view.ViewUtils</function-class>
       <function-signature>
             java.util.List listExcludingSelectedOne(java.util.Collection,java.lang.Object)
       </function-signature>
   </function>   
</facelet-taglib>

Mit entsprechenden Implementierungen der Tag-Funktionalitäten in der ViewUtils-Klasse unter Verwendung generischer Typen T und Collections List<T> hier:

package de.binaris.businessdinners.view;
 
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
 
import javax.persistence.Id;
 
/**
* Utilities for working with Java Server Faces views.
*/
public final class ViewUtils {
 
   public static <T> List<T> asList(Collection<T> collection) {
     if (collection == null) {
         return null;
     }
     return new ArrayList<T>(collection);
   }
 
   public static String display(Object object) {
     if (object == null) {
         return null;
     }
     try {
         // Invoke toString if declared in the class. If not found, 
         // the NoSuchMethodException is caught and handled
         object.getClass().getDeclaredMethod(“toString“);
         return object.toString();
     }
     catch (NoSuchMethodException noMethodEx) {
         try {
           for (Field field : object.getClass().getDeclaredFields()) {
               // Find the primary key field and display it
               if (field.getAnnotation(Id.class) != null) {
                 // Find a matching getter and invoke it to display the key
                 for (Method method : object.getClass().getDeclaredMethods()) {
                     if (method.equals(new PropertyDescriptor(field.getName(),                     
                                         object.getClass()).getReadMethod()))
                     {
                       return method.invoke(object).toString();
                     }
                 }
               }
           }
           for (Method method : object.getClass().getDeclaredMethods()) {
               // Find the primary key as a property instead of a field, and display it
               if (method.getAnnotation(Id.class) != null) {
                 return method.invoke(object).toString();
               }
           }
         } catch (Exception ex) {
           // Unlikely, but abort and stop view generation if any exception is thrown
           throw new RuntimeException(ex);
         }
     }
     return null;
   }
 
   public static <T> int count(Collection<T> collection) {
     if (collection == null) {
               return 0;
     }
     return collection.size();
   }
 
   public static String displayRange(Object object1, Object object2) {
     String text1 = display(object1);
     String text2 = display(object2);
      if (text1 == null || text2 == null
          || text1.trim() == null || text2.trim() == null) {
           return null;
      }
     return (text1 + “-“ + text2);
   }
                
   public static String displayFirst(Object object) {
     String text = display(object);
      if (text == null || text.split(“\\s+“) == null
          || text.split(“\\s+“)[0] == null) {
           return null;
      }
     return (text.split(“\\s+“)[0] + “…“);
   }
 
   public static String displayShort(Object object, int length) {
     String text = display(object);
      if (text == null || text.split(“\\s+“) == null
           || text.split(“\\s+“)[0] == null) {
           return null;
      }
     String[] elements = text.split(“\\s+“);
     String result = ““;
      int i = 0;
      while ((result+elements[i]).length() < length) {
          result += elements[i] + “ “;
          i++;
      }
      return (result.trim() + “…“);
   }

   public static <T> List<T> listExcludingSelectedOne(Collection<T> collection, T selected) {
     if (collection == null) {
         return null;
     }
     if (selected == null) {
       return new ArrayList<T>(collection);
     }
     List<T> list = new ArrayList<T>(collection);
     list.remove(selected);
     return list;
   }
 
   private ViewUtils() {
     // Can never be called, only by getInstance – Singleton pattern
   }

   public static ViewUtils getInstance() {
      return new ViewUtils();
   }
}

Dabei bestimmt allein die Facelets XML-TagLib Deklaration in der forge.taglib.xml, welche der Utility Methoden als Tags mit dem forgeview: Prefix der XML-Namespace Deklaration in den .xhtml-Seiten verfügbar sind und welche ausschließlich als (static) Helper-Funktionen definiert und von anderen Klassen verwendbar sind.

Über Tags, TagLibs und die Erweiterung bestehender und die Definition eigener Tags gibt es bereits einen Blog-Eintrag in diesem Blog hier und durch die soeben gezeigten Beispiele ist erkennbar, wie simpel es ist, eigene Tags für die .xhtml-Views heutiger JSF 2-Applikationen zu definieren und deren Utility functions-Signaturen im WEB-INF/classes/META-INF-Verzeichnis des classpaths als *name*-taglib.xml mit dem folgenden XML Document-Header und dem jboss-forge-view namespace zu deklarieren (s.o. forge.taglib.xml).

Alle XML und XHTML-Dateien der Primefaces-Beispielapplikation finden sich im Deployment-Archiv businessdinners-primefaces.war im /target-Unterverzeichnissen des Projekts businessdinners-primefaces.

Konfiguration des JBoss WildFly 10 Application Servers

Die Konfiguration des JBoss WildFly Application Servers 10 Final erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2 und 9 Final und betrifft die Datasource, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle, sowie die Konfiguration der MySQL-Datenbank Inno DB in vorigen Blog-Einträgen bereits beschrieben worden.

Die Primefaces Beispiel-Applikation arbeitet über die RESTful WebService-Schnittstelle auf der MySQL-InnoDB. Für die Primefaces Beispiel-Applikation kann folgendes mit HeidiSQL erstellte MySQL 5.x Datenbank-Skript verwendet werden. Hier auch die Datasource Definition:

<datasource jndi-name=“java:jboss/datasources/BusinessdinnersDatasource“ pool-name=“BusinessdinnersDS“ enabled=“true“>
            <connection-url>jdbc:mysql://localhost:3306/businessdinners</connection-url>
            <driver>mysql-connector-java-5.1.34.jar</driver>
            <transaction-isolation>TRANSACTION_READ_COMMITTED
            </transaction-isolation>
            <pool>
            <min-pool-size>10</min-pool-size>
            <max-pool-size>100</max-pool-size>
            <prefill>true</prefill>
            </pool>
            <security>
            <user-name>root</user-name>
            <password>[das entsprechende Password]</password>
            </security>
            <statement>
            <prepared-statement-cache-size>32</prepared-statement-cache-size>
            <share-prepared-statements>true</share-prepared-statements>
            </statement>
</datasource>

Die Hibernate-Konfiguration der WildFly Server 9 und 10 ist ebenfalls leicht durchführbar und wurde bereits in einem Blog-Eintrag in diesem Blog hier beschrieben.

Konfiguration der JBoss WildFly 11 Application Servers

Die Konfiguration des JBoss WildFly 11 Final Application Servers erfolgt analog der Konfigurationen der JBoss Application Server WildFly 8.1, 8.2, 9 Final und 10 Final und betrifft die Datasource, das Logging und den Connection Pool und ist, genau wie die Test-Frameworks und die Aktivierung der RESTful WebService-Schnittstelle, sowie die Konfiguration der MySQL-Datenbank Inno DB in vorigen Blog-Einträgen bereits beschrieben worden.

Die Hibernate-Konfiguration des WildFly Servers ist ebenfalls leicht durchführbar. Hierfür werden im WildFly11 Server-Verzeichnis wildfly-11.0.0.Final/modules/system/layers/base/org/hibernate/main folgende Dateien hinterlegt:

– hibernate-core-5.1.10.Final.jar
– hibernate-entitymanager-5.1.10.Final.jar
– hibernate-envers-5.1.10.Final.jar
– hibernate-java8-5.1.10.Final.jar
– jipijapa-hibernate5-11.0.0.Final.jar
– module.xml
– mysql-connector-java-5.1.34.jar
– mysql-connector-java-5.1.34.jar.index

Die WildFly11 module.xml für die Hibernate-Konfiguration kann hier angesehen werden.

Die fertige Beispiel-Applikation businessdinners-primefaces kann leicht selbst deployt werden und kann ebenfalls hier auf dem Test-Server aufgerufen und danach ein Beispiel-Geschäftsessen („Businessdinner“) erstellt und mit den teilnehmenden Gästen versehen werden.

Hier das Beispiel-Projekte für die Eclipse Entwicklungsumgebung JBoss Developer Studio:

JBoss Developer Studio Projekt:

businessdinners-primefaces

Bei dieser Gelegenheit darf auch das sehr effektive, interessante und erfolgreiche Seminar

“TDD mit Java” von Binaris Informatik ebenfalls positiv erwähnt werden.

Hier der WildFly 10 Final als Zip-Archiv zum Download und Entpacken: Für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank für den WildFly 9 und den WildFly 10 gibt es hier mehr Informationen in diesem Blog.

Die fertig konfigurierte Version des WildFly 10.0.0.Final mit vielen Beispiel-Applikationen der vorigen Blog-Einträge hier zum Download bereit, kann runtergeladen, entpackt und gestartet werden. Dabei ist nur der Pfad für JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 8 – Verzeichnis des Server-Systems zeigt.

Hier auch der neue WildFly 11 als Zip-Archiv zum Download und Entpacken, für Linux hier und für Windows hier. Voraussetzung ist jeweils Java 8. Über die Konfiguration von Hibernate, der Datasource und der MySQL 5.x Datenbank wird ebenfalls auf bereits vorhandene Blog-Einträge hier verwiesen, da die Konfigurationen analog zum WildFly 9 und WildFly 10 durchzuführen sind.

Der fertig konfigurierte WildFly 11 mit vielen Beispiel-Applikationen der vorangegangenen Blog-Einträge ist hier zum Download verfügbar, kann runtergeladen, entpackt und gestartet werden. Auch hier ist nur der Pfad des JAVA_HOME anzupassen, damit dieser auf das tatsächliche JDK 9 – Verzeichnis des Server-Systems zeigt.

Mehr Informationen zum kürzlichen erschienenen Java 9 Release gibt es hier:

https://www.technotification.com/2017/09/java-9-is-finally-released.html

Herunterladen kann man sich das neue Java 9 für die gewünschte Betriebssystem-Plattform hier:

http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html

In Fällen mit Migrations-Bedarf gibt es hier weitere Informationen.

Hier die Release-Notes zu Java 9:

http://www.oracle.com/technetwork/java/javase/9-relnotes-3622618.html

Die SQL-Skripte zum Anlegen und Befüllen der MySQL Beispiel-Datenbanken finden sich verlinkt in den Blog-Einträgen wieder, die hier durchsucht werden können, durch Eingabe eines Stichworts des Titels oder Blog-Eintrag Texts im Feld Suche… der Eingabemaske.

Hier auch nochmal die ausführliche Dokumentation einer weiteren JEE Beispielapplikation mit REST-Webservices getriebenem Angular JS Frontend. Und hier noch eine weitere SPA (Single Page Appliction) Beispiel-Applikation, bei der das Testen des Backends mittels Arquillian und das integrative Testen des Frontends mittels Selenium (Workflow und UX Elemente) und QUnit  (Javascript-Framework zum Test-Aufruf der REST-Endpoints aus einer Browser-View) ebenfalls ausführlich beschrieben ist.

Die Primefaces Beispiel-Applikation dieses Blog-Eintrags kann auch selbst erneut deployt werden, ohne den bereits gestarteten WildFly Application Server überhaupt stoppen oder erneut starten zu müssen. Bei laufendem Server einfach ins Server-Unterverzeichnis /standalone/deployments

– eine leere Textdatei namens shoppinghelper-primefaces.war.dodeploy speichern und
– das Archiv shoppinghelper-primefaces.war aus dem shoppinghelper-primefaces/target-Verzeichnis speichern

Wie man sieht, macht es viel Freude, JEE-Applikationen mit der vorteilhaften Primefaces-Technologie zu entwickeln und ebenfalls, zuvor die Faces-Beispielapplikationen mittels JBoss Forge auf dem Datenmodell zu erzeugen und weiterzuentwickeln.

Es ist also sehr wahrscheinlich, dass noch weitere Blog-Einträge zu Webframeworks wie Primefaces, Angular JS und Faces und den die JEE-Spezifikation implementierenden Technologien folgen.

Allen interessierten Leserinnen und Lesern weiterhin viel Freude bei der agilen Softwareentwicklung mittels Scrum und dem Test Driven Development mit Java, sowie eine schöne vorweihnachtliche Zeit und viel Freude bei den Weihnachtsfeiern.