Services – mit Hibernate 4, Vaadin 6, JBoss 7

Freitag, 28. Februar 2014 von  
unter Fachartikel Architektur

 Die Motivation

Der JBoss 7 Application Server ist aus den IT-Server System-/und Software-Architekturen zeitgemäßer, moderner Unternehmensanwendungen und JavaEE Applikationen nicht mehr wegzudenken und bietet darüber hinaus viele Möglichkeiten der Variation und Austauschbarkeit der Software-Systemkomponenten. Dies wird ermöglicht durch die modulare Server-Konfiguration (Services, die zur Startzeit oder später gestartet werden können) zur Unterstützung von Persistenz-Frameworks, wie z.B. Hibernate. Über Services mit JPA und Hibernate und Service-Architekturen mit Hibernate gibt es bereits Blog-Einträge in diesem Blog. Da Hibernate und der JBoss genauso wie das Linux-Derivat „RedHat“ von RedHat gehostet werden, kann man vorteilhafterweise davon ausgehen, mit dem Download einer neueren JBoss-Version (Brontes, WildFly, etc.) auch gleich eine der aktuellsten Hibernate Versionen kostenfrei (Open Source) mitgeliefert zu bekommen. In diesem Blog-Eintrag handelt es sich dabei um Hibernate 4.x.x auf dem JBoss 7 (Brontes). Da es bereits einen Blog-Eintrag über eine Vaadin-Beispiel-App auf dem GlassFish Application Server in diesem Blog gibt, welche mit NetBeans entwickelt wurde, soll in diesem Blog-Eintrag mit dem JBoss Developer Studio (Vers.5 basiert z. B. auf Eclipse Indigo) nun eine Vaadin 6 Beispiel-JavaEE-Applikation für den JBoss entwickelt werden. Die Portierung dieser Beispiel-App auf Vaadin 7 wird danach für einen erfahrenen Web-Fontend-Entwickler zu den kleineren Aufwendungen gehören.

Über TDD für den JBoss mit TestNG gibt es auch bereits einen Blog-Eintrag hier. An dieser Stelle darf auf die sehr empfehlenswerten „Test-Driven Development mit Java“ Seminare von Binaris hier hingewiesen werden.

MySQL-/Hibernate-Konfiguration als Server-Modul (Persistenz-Service)

Über die Struktur des Beispiel-Projekts „mapperApp“ wurde anhand eines vorigen Blog-Eintrags über ein Seam-JavaEE-Beispiel-Projekt hier bereits berichtet, weshalb die Hibernate-Konfiguration im Projekt mittels hibernate.cfg.xml und persistence.xml hier nicht wiederholt wird, aber die Bekanntmachung des MySQL-JDBC4-Treibers für die Hibernate 4-Unterstützung und die Definition der zugehörigen Datasource für die Beispiel-App sollen nun erklärt werden:

In der /standalone/standalone.xml wird die folgende Datasource unter <datasources> definiert:

<datasource jndi-name=“java:/mapperAppDatasource“ pool-name=“mapperAppDS“ enabled=“true“ use-java-context=“true“>

    <connection-url>jdbc:mysql://localhost:3306/addressbook?useUnicode=true&amp;characterEncoding=UTF-8 
    </connection-url>
    <connection-property name=“autoReconnect“>true
    </connection-property>

    <driver>mysql-connector-java-5.1.17.jar</driver>
    <security>
        <user-name>root</user-name>
        <password>router</password>
    </security>
</datasource>

Weiterhin erfolgt in der /standalone/standalone.xml unter <drivers> der folgende Driver-Eintrag für den MySQL-Hibernate-Treiber:

<driver name=“mysql-connector-java-5.1.17.jar“ module=“com.mysql“/>

Das von mysql-connector-java-5.1.17-bin.jar nach mysql-connector-java-5.1.17.jar umbenannte Treiber-JAR wird auch ins Verzeichnis /standalone/deployments kopiert. Sicherheitshalber kann der MySQL-Treiber auch noch als Server-Modul bekanntgemacht werden. Hierfür legt man im Verzeichnis /modules/mysql/main die folgende module.xml an:

<?xml version=“1.0″ encoding=“UTF-8″?>
<!–
  ~ JBoss, Home of Professional Open Source.
  ~ Copyright 2010, Red Hat, Inc., and individual contributors
  ~ as indicated by the @author tags. See the copyright.txt file in the
  ~ distribution for a full listing of individual contributors.
  ~

  ~ This is free software; you can redistribute it and/or modify it
  ~ under the terms of the GNU Lesser General Public License as
  ~ published by the Free Software Foundation; either version 2.1 of
  ~ the License, or (at your option) any later version.
  ~
  ~ This software is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  ~ Lesser General Public License for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public
  ~ License along with this software; if not, write to the Free
  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  –>

<module xmlns=“urn:jboss:module:1.1″ name=“com.mysql“>
    <resources>
        <resource-root path=“mysql-connector-java-5.1.17.jar“/>
        <!– Insert resources here –>
    </resources>
    <dependencies>
        <module name=“javax.api“/>
    </dependencies>
</module>

Dann kopiert man das von mysql-connector-java-5.1.17-bin.jar nach mysql-connector-java-5.1.17.jar umbenannte Treiber-JAR ebenfalls in das Verzeichnis /modules/mysql/main. Danach wird der Treiber auch dem Hibernate 4,x,x Server Modul bekanntgemacht. Dafür kopiert man das von mysql-connector-java-5.1.17-bin.jar nach mysql-connector-java-5.1.17.jar umbenannte Treiber-JAR ebenfalls in das Verzeichnis /modules/org/hibernate/main und ändert die Datei /modules/org/hibernate/main/module.xml wie folgt:

<?xml version=“1.0″ encoding=“UTF-8″?>
<!–
  ~ JBoss, Home of Professional Open Source.
  ~ Copyright 2011, Red Hat, Inc., and individual contributors
  ~ as indicated by the @author tags. See the copyright.txt file in the
  ~ distribution for a full listing of individual contributors.
  ~
  ~ This is free software; you can redistribute it and/or modify it
  ~ under the terms of the GNU Lesser General Public License as
  ~ published by the Free Software Foundation; either version 2.1 of
  ~ the License, or (at your option) any later version.
  ~
  ~ This software is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  ~ Lesser General Public License for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public
  ~ License along with this software; if not, write to the Free
  ~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  ~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  –>
<!– Represents the Hibernate 4.0.x module–>
<module xmlns=“urn:jboss:module:1.1″ name=“org.hibernate“>
    <resources>
        <resource-root path=“hibernate-core-4.0.1.Final.jar“/>
        <resource-root path=“hibernate-commons-annotations-4.0.1.Final.jar“/>
        <resource-root path=“hibernate-entitymanager-4.0.1.Final.jar“/>
        <resource-root path=“hibernate-infinispan-4.0.1.Final.jar“/>
        <!– Insert resources here –>
        <resource-root path=“mysql-connector-java-5.1.17.jar“/></resources>
    <dependencies>
        <module name=“asm.asm“/>
        <module name=“javax.api“/>
        <module name=“javax.persistence.api“/>
        <module name=“javax.transaction.api“/>
        <module name=“javax.validation.api“/>
        <module name=“org.antlr“/>
        <module name=“org.apache.commons.collections“/>
        <module name=“org.dom4j“/>
        <module name=“org.infinispan“ optional=“true“/>
        <module name=“org.javassist“/>
        <module name=“org.jboss.as.jpa.hibernate“ slot=“4″ optional=“true“/>
        <module name=“org.jboss.logging“/>
        <module name=“org.hibernate.envers“ services=“import“ optional=“true“/>
    </dependencies>
</module>

Das deployte EAR namens „mapperApp.ear“ wird ebenfalls ins Verzeichnis /standalone/deployments neben den MySQL-Treiber kopiert und eine leere Datei namens „mapperApp.ear.dodeploy“ im selben Verzeichnis angelegt, damit das Modul deployt wird (z.B. direkt beim Server-Start).

Der Server kann dann entweder im Eclipse aus der Server-View gestartet werden oder mittels Batch oder Shell-Skript „standalone.bat“ bzw. „standalone.sh“. Das deployte „mapperApp.ear“ hat dabei die folgende Struktur:

+ mapperApp.ear
– mapperApp.war
– META-INF
– application.xml
– jboss-app.xml

Und das mapperApp.war hat die folgende Struktur:

+ mapperApp.war
– META-INF
– MANIFEST.MF
– persistence.xml
– WEB-INF
– classes
– lib
– web.xml

Das WEB-INF/classes – Verzeichnis hat den bereits im Blog-Eintrag hier beschriebenen Aufbau. Der WebApplication-Deployment Descriptor „web.xml“ wurde bereits in diesem Blog-Eintrag hier beschrieben und sieht so aus:

<?xml version=“1.0″ encoding=“UTF-8″?>
<web-app version=“3.0″ xmlns=“http://java.sun.com/xml/ns/javaee“
 xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
 xsi:schemaLocation=“http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd“>
    <context-param>
        <description>Vaadin production mode</description>
        <param-name>productionMode</param-name>
        <param-value>false</param-value>
    </context-param>
    <servlet>
        <servlet-name>MapperApplication</servlet-name>
        <servlet-class>com.vaadin.terminal.gwt.server.ApplicationServlet</servlet-class>
        <init-param>
            <description>Vaadin application class to start</description>
            <param-name>application</param-name>
            <param-value>de.binaris.vaadin.registration.MapperApplication</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>MapperApplication</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Die MapperApplication.java, die zur Buildtime in eine Servlet-Klasse compiliert wird, hat den folgenden Inhalt:

package de.binaris.vaadin.registration;
import com.vaadin.ui.Label;
import com.vaadin.ui.Window;
import de.binaris.vaadin.registration.ui.components.ComponentAlignmentLayout;
import de.binaris.vaadin.registration.workflow.WorkflowEngine;
 
public class MapperApplication extends com.vaadin.Application {
    private static final long serialVersionUID = 7773278487293700727L;
    public static final String PERSISTENCE_UNIT=“mapperApp“;
 
    private final WorkflowEngine wfEngine;
    private final Window mainWindow;
 
    private ComponentAlignmentLayout layout;
 
    public MapperApplication() {
        mainWindow = new Window(„Mapper Application“);
        wfEngine = new WorkflowEngine();
    }

    @Override
    public void init() {
        mainLabel = new Label(„Mapper Application“);
        layout = new ComponentAlignmentLayout(this);
       
        mainWindow.addComponent(layout);
        setMainWindow(mainWindow);
    }

    public WorkflowEngine getWorkflowEngine() {
        return wfEngine;
    }
}

Die application.xml des mapperApp.ear sieht so aus:

<?xml version=“1.0″ encoding=“UTF-8″?>
<application xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“ xmlns=“http://java.sun.com/xml/ns/javaee“ xmlns:application=“http://java.sun.com/xml/ns/javaee/application_5.xsd“ xsi:schemaLocation=“http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd“ id=“Application_ID“ version=“6″>
  <display-name>mapperApp</display-name>
  <module>
    <web>
      <web-uri>mapperApp.war</web-uri>
      <context-root>mapperApp</context-root>
    </web>
  </module>
</application>

Die jboss-app.xml des mapperApp.ear sieht so aus:

<?xml version=“1.0″ encoding=“UTF-8″?>
  <!DOCTYPE jboss-app
    PUBLIC „-//JBoss//DTD J2EE Application 4.2//EN“
    „http://www.jboss.org/j2ee/dtd/jboss-app_4_2.dtd“>
<jboss-app>
   <loader-repository>
      seam.jboss.org:loader=mapperApp
   </loader-repository>
</jboss-app>

 Die Datenbank anlegen

Hier noch das Command-Line Skript zur Erzeugung der Datenbank-Tabellen:

create database addressbook;
use addressbook;
CREATE TABLE IF NOT EXISTS `MAPPER_APPLICATION` (
  `ID_MAPPER_APPLICATION` BIGINT NOT NULL AUTO_INCREMENT,
  `NAME` VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (`ID_MAPPER_APPLICATION`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
CREATE TABLE IF NOT EXISTS `MAPPER_ENTITY_TYPE` (
  `ID_MAPPER_ENTITY_TYPE` BIGINT NOT NULL AUTO_INCREMENT,
  `NAME` VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (`ID_MAPPER_ENTITY_TYPE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
CREATE TABLE IF NOT EXISTS `MAPPER_ENTITY` (
  `ID_MAPPER_ENTITY` BIGINT NOT NULL AUTO_INCREMENT,
  `NAME` VARCHAR(255) DEFAULT NULL,
  `ID_MAPPER_ENTITY_TYPE` BIGINT NOT NULL,
  PRIMARY KEY (`ID_MAPPER_ENTITY`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
CREATE TABLE IF NOT EXISTS MAPPER_ALIAS (
  `ID_MAPPER_ALIAS` BIGINT NOT NULL AUTO_INCREMENT,
  `ALIAS`           VARCHAR(255) DEFAULT NULL,
  `ID_MAPPER_APPLICATION` BIGINT NOT NULL,
  `ID_MAPPER_ENTITY` BIGINT NOT NULL,
  PRIMARY KEY (`ID_MAPPER_ALIAS`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Aus diesen Datenbank-Tabellen sind die benötigten JPA-Entities schnell mit Hilfe eines hierfür angelegten JPA-Projekts erzeugt („File/New/Other/JPA/JPA Project“). Danach auf dem Projekt im Kontext-Menü „New/Other/JPA/ JPA Entities from Tables“ auswählen. Die Vorgehensweise zur Generierung und Erweiterung der benötigten Entities wurde bereits in den Blog-Einträgen hier und hier genauer beschrieben. Anzumerken ist noch, dass der Query-Cache der angelegten MySQL-Datenbank hier nicht benötigt wurde und deshalb für diese DB deaktiviert wurde: mysql> SET SESSION query_cache_type = OFF;

Zu den Security-Aspekten von Vaadin-Applikationen gibt es hier auch noch weitere Informationen zusätzlich zu den Informationen, die bereits allgemein zu Java WebApps aus dem SCWCD bzw. OCWCD bekannt sind:

(Vaadin Application Security Webinar) http://www.youtube.com/watch?v=PNAo3ApWA-A

Und hier der Sourcecode zum Webinar. https://github.com/vaadin-kim/shiro-example

Für interessierte Vaadin 7 Entwickler gibt es hier den Link zur Online-Zertifizierung: https://vaadin.com/certification

Die Beispiel App

Die kleine Beispiel-App ist mit dem JBoss Developer Studio schnell erstellt. Der Klick-Pfad hierfür ist File/New/Project/Other/ Web Project. Da es über die Architektur im Blog-Eintrag „Service-Architekturen mit Hibernate“ bereits genügend Informationen (und Open Source Sourcecode) gibt und die verwendete „State Machine“ der ansatzweise implementierten Workflow Engine gut erkennbar sein dürfte, wird der Sourcecode hier nicht weiter erklärt. Deshalb hier nur kurz die Package-Struktur der Beispiel App mit dem Basis-Package de.binaris.vaadin.registration:

– base
– dao
– db
– domain
– jpa
– model
– ui
– workflow
MapperApplication.java

Die Transaktionen

Zwei Besonderheiten zur Beispiel-App, die ganz ohne geschickte JPA-Mappings auskommt, sondern für die vier Beispiel-Tabellen Hibernate auf Basis simplen JDBCs nutzt: 1. Die Transaktionsklammer ist hier prinzipiell auf DAO-Ebene gelegt, kann aber, wie beispielhaft geschehen, auch auf höhere fachliche Ebenen verlagert werden. Und 2. Wenn eine Transaktion bereits läuft, muss diese beendet werden, bevor eine neue Transaktion gestartet werden kann. Beispielhaft kann dies nach dem Try-and-Error Prinzip mit einem simplen try {…} catch(Exception e) {…} folgendermaßen implementiert werden:

boolean transactionRunning = false;
try {
    jpaAliasFacade.getSession().beginTransaction();
    transactionRunning = true;
} catch (Exception e) {
    jpaAliasFacade.getSession().getTransaction().commit();
    transactionRunning = false;
}
if (transactionRunning == false) {
    jpaAliasFacade.getSession().beginTransaction();
}
// … auszuführen innerhalb der Transaktion, danach:
jpaAliasFacade.getSession().getTransaction().commit();
 

Hier der Link zum EAR und der Download-Link mit dem Sourcecode der Applikation:

EAR: http://www.4shared.com/zip/gY66jDvnce/mapperAppear.html

Src: http://www.4shared.com/zip/qxauQXRvce/src.html

Die Download-Url für den JBoss 7.1.1 (Brontes) lautet:
http://download.jboss.org/jbossas/7.1/jboss-as-7.1.1.Final/jboss-as-7.1.1.Final.zip
Die Aufruf-Url der deployten Beispiel-Applikation lautet für nicht geänderte http(s)-Ports des laufenden JBoss Servers: http://localhost:8080/mapperApp/

Weitere Vaadin 6-Samples finden sich hier (sampler.war): http://www.4shared.com/file/i24rQFa3ba/sampler.html

Hier noch die RefCard-Updates von DZone zu Vaadin und Vaadin7.

Und hier noch ein paar interessante Vaadin PDFs:
book-of-vaadin6.pdf
book-of-vaadin7.pdf
vaadin-jpa-container-Manual.pdf

Und hier auch der offizielle Vaadin channel.

Allen interessierten Leserinnen und Lesern noch eine verantwortungsvolle Karnevals-Session und einen schönen Frühlingsanfang 2014.

Kommentare

5 Kommentare zu “Services – mit Hibernate 4, Vaadin 6, JBoss 7”

  1. Von Services – mit jBPM6, JBoss, TDD : binaris informatik GmbH am Sonntag, 25. Mai 2014 17:24

    […] verbessern. Die Idee hierzu entstand bei einem Blog-Eintrag über Hibernate 4, JBoss 7 und Vaadin 6 hier, wobei der Ansatz einer  proprietären State Machine zum Einsatz kam, und es wäre sicherlich eine […]

  2. Von Architekturen – mit Spring CDI, JPA, JBoss, JavaEE : binaris informatik GmbH am Dienstag, 1. Juli 2014 22:10

    […] (z. B. für den Einsatz einer bestimmten Datasource mit dem JBoss-eigenen Hibernate, worüber es hier bereits einen Blog-Eintrag gibt), erfolgt dann die Java EE Konfiguration der Applikation. Z.B. ist […]

  3. Von Services – TDD mit Arquillian, JSF2, JEE6, CDI : binaris informatik GmbH am Donnerstag, 30. April 2015 10:30

    […] wie es in diesem Blog-Eintrag mit dem Titel “Services – mit Hibernate 4, Vaadin 6, JBoss 7“ hier beschrieben […]

  4. Von Services – TDD mit Selenium, QUnit JS, JEE6 : Softwareentwicklung, Projektmanagement & Schulung | binaris informatik GmbH am Dienstag, 12. Mai 2015 09:43

    […] wie es in diesem Blog-Eintrag mit dem Titel “Services – mit Hibernate 4, Vaadin 6, JBoss 7“ hier beschrieben […]

  5. Von Services – TDD mit Vaadin Testbench, Java, Hibernate, JBoss : Softwareentwicklung, Projektmanagement & Schulung | binaris informatik GmbH am Sonntag, 26. Juli 2015 18:58

    […] und Hibernate für den JBoss AS entwickelte Beispiel-Applikation gibt es bereits einen Blog-Eintrag hier. Zum Erstellen sinnvoller Tests für diese und andere Vaadin Web-Applikationen soll die “Vaadin […]

Einen Kommentar hinzufügen...

Sie müssen registriert und angemeldet sein um einen Kommentar zu schreiben.