Java EE 
Full Stack for Business Applications
Java EE 
Full Stack for Business Applications 
 2014-12-11 Q&A
Referent: MATTHIAS REINING 
Technical Manager Insurance at RGI Deutschland GmbH 
blog: http://blog.matthias-reining.com 
t...
Q&A 
Question & Answers
Aber zuerst… 
… kurze Wiederholung
DAS PROGRAMM 
 Die Spec 
 Idee, Historie 
 Der App Server 
 Containerkonzept 
 Paketierung (JAR, WAR, EAR) 
 Marktüb...
DAS PROGRAMM 
 Die Spec 
 Idee, Historie 
 Der App Server 
 Containerkonzept 
 Paketierung (JAR, WAR, EAR) 
 Marktüb...
Question 
>>>> 
Wir versuchen gerade das Projekt zum laufen zu bekommen. Mir ist 
nicht ganz klar wie sich unsere Applikat...
ANSWER 
Applikation – Datenbank 
Eine Java EE Applikation kennt idealerweise NIE direkt die Datenbank. 
Somit ist es mögli...
ANSWER 
Application / persistence.xml 
Die Datasource wird beim Einsatz von JPA in der persistence.xml angegeben 
(https:/...
ANSWER 
Application Server Konfiguration 
Der Application Server kann verschieden Datasources verwalten. Dies kann über di...
ANSWER 
H2 – username/password 
Die H2 Datenbank legt automatisch eine Datenbank (File auf der Platte) an, 
wenn noch kein...
ANSWER 
Zweite persistence.xml 
Die zweite persistence.xml ist wie sie schreiben nur für den Test und 
auch eine In-Memory...
Question 
>>>> 
ich habe es gerade noch einmal ausprobiert. h2 datenbank im server 
modus starten, wildfly server starten,...
ANSWER 
Datenbank Problem: 
Ich bekomme die gleiche Fehlermeldungen wenn ich 
1. Die Datenbank nicht gestartet habe. 
Dies...
Question 
1. Beim Aufruf der listJobs-View mit unten stehender Adresse 
bekomme ich die Servlet Exception im Anhang. Wo li...
ANSWER 
Zur Datasource: 
Ich würde den Treiber mysql-xyz.jar in das Deployment Verzeichnis kopieren 
(einfache Variante, s...
ANSWER 
ich habe die Anwendung auf github geforkt: https://github.com/mr678/auftragsverwaltung. Wenn alles gefunzt hat, ha...
QUESTION 
d.h. in den Backing Beans arbeite ich immer ohne Konstruktoren, 
stattdessen mit der init()-Methode und muss dan...
ANSWER 
Konstruktoren: 
Alle von einem Container gemangten Objekte benötigen immer auch einen Non-Parameter Kontruktor 
(w...
ANSWER 
Der Grobe Lifecycle 
 Container legt Objekt an 
 Felder bei denen direkt Objekte angelegt werden, werden ausgefü...
Question 
• #1: Warum ist checkPassword() in der Entity definiert und nicht im 
UserService? 
• #2: Was ist der Unterschie...
ANSWER 
#1: Warum ist checkPassword() in der Entity definiert und nicht im 
UserService? 
Hier gibt es unterschiedliche An...
ANSWER 
#2: Was ist der Unterschied zwischen Boundary (UserService) und Controller (PWService)? Sind Boundaries 
Controlle...
ANSWER 
#3: Wieso verwendet UserService kein begin()/commit() und CreateDummyUser die UserTransaction und 
nicht die Metho...
ANSWER 
#4: Für was ist das init() in TestServletTest gut? 
Die Methode init() ist mit der Annotation @Before von jUnit ge...
ANSWER 
#5: Werden wir in der nächsten Vorlesung den Login mit Rest programmieren?! 
Wenn dann am SA – für FR steht CDI au...
Nächste SlideShare
Wird geladen in …5
×

Java EE - FHWS 2014 - 5.5 Q&A

484 Aufrufe

Veröffentlicht am

Question & Answers

Veröffentlicht in: Software
0 Kommentare
0 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Keine Downloads
Aufrufe
Aufrufe insgesamt
484
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
5
Aktionen
Geteilt
0
Downloads
8
Kommentare
0
Gefällt mir
0
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Java EE - FHWS 2014 - 5.5 Q&A

  1. 1. Java EE Full Stack for Business Applications
  2. 2. Java EE Full Stack for Business Applications  2014-12-11 Q&A
  3. 3. Referent: MATTHIAS REINING Technical Manager Insurance at RGI Deutschland GmbH blog: http://blog.matthias-reining.com twitter: https://twitter.com/MatthiasReining about.me: http://about.me/matthiasreining
  4. 4. Q&A Question & Answers
  5. 5. Aber zuerst… … kurze Wiederholung
  6. 6. DAS PROGRAMM  Die Spec  Idee, Historie  Der App Server  Containerkonzept  Paketierung (JAR, WAR, EAR)  Marktüberblick  Das Projekt  Entwicklung eines Beispielprojektes  IDE Settings, Oberflächen (Servlets, JSF), Business Logic (EJB), Persistence (JPA), Java EE Patterns (CDI), Web Services (JAX-RS)  Die Produktion  Buildmanagement (maven, Jenkins)  Deployment einer Java EE Anwendung in der Cloud bei einem PaaS Anbieter
  7. 7. DAS PROGRAMM  Die Spec  Idee, Historie  Der App Server  Containerkonzept  Paketierung (JAR, WAR, EAR)  Marktüberblick  Das Projekt  Entwicklung eines Beispielprojektes  IDE Settings, Oberflächen (Servlets, JSF), Business Logic (EJB), Persistence (JPA), Java EE Patterns (CDI), Web Services (JAX-RS)  Die Produktion  Buildmanagement (maven, Jenkins)  Deployment einer Java EE Anwendung in der Cloud bei einem PaaS Anbieter
  8. 8. Question >>>> Wir versuchen gerade das Projekt zum laufen zu bekommen. Mir ist nicht ganz klar wie sich unsere Applikation mit der Datenbank verbindet. Ich weiß auch nicht genau was ich in der h2 config eintragen muss. Benutzername und Passwort sind im Code nicht eingetragen. Und die der zweiten persistence.xml ist denk ich mal noch von dem memory test. Aber es funktioniert ja irgendwie so, dass es sowohl mit h2 lokal als auch mit MySQL auf dem Server funktioniert. <<<<
  9. 9. ANSWER Applikation – Datenbank Eine Java EE Applikation kennt idealerweise NIE direkt die Datenbank. Somit ist es möglich eine Java EE Applikation zu entwickeln die unabhängig vom eingesetzten RDBMS ist (H2, MySQL, Oracle, …)  Die Java EE Applikation connected sich zur Datenbank über eine Datasource.  Die Datasource wird in der Application Server Konfiguration definiert mit dem konkreten Bezug zu einer Datenbank H2 oder MySQL.  Der Applikation wird die Datasource in persistence.xml bekannt gemacht:
  10. 10. ANSWER Application / persistence.xml Die Datasource wird beim Einsatz von JPA in der persistence.xml angegeben (https://github.com/mr678/fhws- 2014/blob/master/src/main/resources/META-INF/persistence.xml). In der persistence.xml wird auch eine „persistence-unit“ definiert (PU). Dies ist sinnvoll, wenn eine Java EE Applikation mit mehrere Datenbanken spricht. Bei der Annotation @PersistenceContext kann man dann über den „unitName“ die passende ansprechen. Wird nur eine Persistence Unit verwendet braucht man keine weiteren Angaben bei der Annotation; wie in unserer Beispielapplikation. Wichtig ist daher in unserem Beispiel nur die „jta-data-source“: java:jboss/datasources/FHWS-DS
  11. 11. ANSWER Application Server Konfiguration Der Application Server kann verschieden Datasources verwalten. Dies kann über die Administrationsoberfläche (localhost:9990) gemacht werden oder per Konfigurationsdatei (in unserem Beispiel : wildfly-8.1.0.Final/standalone/configuration/standalone.xml): <datasource jndi-name="java:jboss/datasources/FHWS-DS" pool-name="FHWS-DS" enabled="true" use-java-context=" true"> <connection-url>jdbc:h2:tcp://localhost/D:/fhws/servers/database/fhws-db</connection-url> <driver>h2</driver> <security> <user-name>sa</user-name> <password>sa</password> </security> </datasource> In dem Snippet sehen sie den Parameter “jndi-name”. Dies ist der Name unsere Datasource die mit dem Eintrag in der persistence.xml matchen muss. Die Server Konfiguration (standalone.xml) habe ich gerade eben noch in GitHub eingecheckt (https://github.com/mr678/fhws- 2014/blob/master/src/main/script/wildfly-configuration/standalone.xml)
  12. 12. ANSWER H2 – username/password Die H2 Datenbank legt automatisch eine Datenbank (File auf der Platte) an, wenn noch keines da ist. Hierbei wird automatisch das angegebene Passwort verwendet. Ist bereits eine Datenbank vorhanden muss immer das Passwort von der Anlage verwendet werden. Das Password selbst wird in der standalone.xml in unserem Beispiel eingetragen. In unserem Beispiel im Klartext. Dies ist auch oft ausreichend, da dies nur für Admins zugänglich ist, die eh Zugriff auf den Server haben. Für den Fall, dass man den Admin nicht vertraut und der App-Server Admin keinen Zugriff auf den DB-Server haben darf, kann man dieses PW auch verschlüsselt hinterlegen. Wie? Einfach mal googlen ;-)
  13. 13. ANSWER Zweite persistence.xml Die zweite persistence.xml ist wie sie schreiben nur für den Test und auch eine In-Memory Datenbank.
  14. 14. Question >>>> ich habe es gerade noch einmal ausprobiert. h2 datenbank im server modus starten, wildfly server starten, in admin console neue jdbc datasource hinzufügen (bzw. per hand in standalone.xml) und auf "test connection" drücken. und genau dass geht nicht. da bekomme ich den fehler aus der letzten mail: "connection is not valid". <<<<<
  15. 15. ANSWER Datenbank Problem: Ich bekomme die gleiche Fehlermeldungen wenn ich 1. Die Datenbank nicht gestartet habe. Diese muss manuell gestartet werden. Am einfachsten auf der Konsole im Verzeichnis mit der h2-jar Datei: java -jar h2-1.3.173.jar oder 2. Das Passwort nicht passt. In der eingecheckten standalone.xml ist als Password „sa“ angegeben. Das Passwort wird beim Erstellen der DB mit dem ersten Login festgelegt. Wenn Sie bspw. ihre Datenbankdatei löschen (in unserem Beispiel: fhws-db.h2.db) und die H2 erneut starten, können Sie im Web-Interface sich auf die entsprechende Datenbank connection. Das Passwort, dass Sie bei der ersten Verbindung wählen ist anschließend auch das Passwort, dass Sie in der standalone.xml angeben müssen Die Fehlermeldungen sind in beiden Fällen nicht unbedingt toll und könnten den Fehler besser beschreiben.
  16. 16. Question 1. Beim Aufruf der listJobs-View mit unten stehender Adresse bekomme ich die Servlet Exception im Anhang. Wo liegt der Fehler? http://localhost:8080/Auftragsverwaltung-1.0-SNAPSHOT/listJobs.jsf 2. Wie installiere ich den mysql-connector dauerhaft auf dem Wildfly? Ich mache es momentan über das Runtime Deployment Management in der Admin Console, das verschwindet jedoch immer wieder.
  17. 17. ANSWER Zur Datasource: Ich würde den Treiber mysql-xyz.jar in das Deployment Verzeichnis kopieren (einfache Variante, so haben wir das bei dem Bitnami-Cloud-Server gemacht). Alternativ können Sie auch ein JBoss/Wildfly Modul packen mit dem MySQL Treiber. Die Konfiguration würde ich direkt in der standalone.xml vornehmen und nicht über die Admin Oberfläche. Hier können Sie auch kontrollieren ob die Änderungen angenommen worden sind. Wenn Sie googlen nach Wildfly oder Jboss und MySQL driver install finden Sie viele Beispiele (https://docs.jboss.org/author/display/WFLY8/DataSource+configuration)
  18. 18. ANSWER ich habe die Anwendung auf github geforkt: https://github.com/mr678/auftragsverwaltung. Wenn alles gefunzt hat, haben Sie auch github einen pullrequest erhalten. Als erstes habe ich die Datasource auf Example DS geändert, damit ich bei mir nicht allzu viel einrichten muss. Beim Aufruf ihrer „Problemseite“ habe ich Browser folgende Fehlermeldung bekommen: Context Path:/Auftragsverwaltung-1.0-SNAPSHOT Servlet Path:/listJobs.jsf Path Info:null Query String:null Stack Trace javax.servlet.ServletException: Bei der Ressourcen-Einspeisung auf dem verwalteten Bean jobListProducer ist ein Fehler aufgetreten. javax.faces.webapp.FacesServlet.service(FacesServlet.java:659) io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) Ist mehr oder wengier “bla bla bla”. Wichtig ist hier, dass Sie immer auch auf der Server schauen. Dies liegt daran, dass viele Frameworks (in diesem Fall JSF) verschiedene Wrapper und Abstraktionsschichten um den eigentlichen Code legen. Daher sieht man nicht immer direkt die Fehlermeldung im Browser. Im Server: 19:46:04,669 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (default task-13) Error Rendering View[/listJobs.xhtml]: com.sun.faces.mgbean.ManagedBeanCreationException: Bei der Ressourcen-Einspeisung auf dem verwalteten Bean jobListProducer ist ein Fehler aufgetreten. at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:227) [jsf-impl-2.2.6-jbossorg-4.jar:] at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:103) [jsf-impl-2.2.6-jbossorg-4.jar:] at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:409) [jsf-impl-2.2.6-jbossorg-4.jar:] „1000“ Zeilen im Logfile später Caused by: java.lang.NullPointerException at de.fresko.auftragsverwaltung.data.JobListProducer.createMockJobs(JobListProducer.java:39) [classes:] at de.fresko.auftragsverwaltung.data.JobListProducer.init(JobListProducer.java:20) [classes:] ... 97 more Und hier ist auch schon das Problem: NullPointerException in JobListProducer#createMockJobs Line 39 Fix in Line 17: private List<Auftrag> jobs = new ArrayList<>();
  19. 19. QUESTION d.h. in den Backing Beans arbeite ich immer ohne Konstruktoren, stattdessen mit der init()-Methode und muss dann aber die Felder schon bei der Deklaration vorinitialisieren?
  20. 20. ANSWER Konstruktoren: Alle von einem Container gemangten Objekte benötigen immer auch einen Non-Parameter Kontruktor (weitere Konstruktoren sind hier aber natürlich erlaubt). Gemangte Objekte: Servlets, Filter, Listener, JSF Managed Beans, EJBs, CDI Objekte, RESTful Servlets Wieso? Der Container initalisiert diese Objekte (via Reflection API, habe ganz am Anfang mal gezeigt wie das funktioniert – der Container macht da auch nichts anders…) Nachdem der Container die Parameter nicht kennen kann, benötigt er immer auch einen leeren Konstruktor zum Anlegen der Objekte. Das heißt der Container verwaltet den Lifecycle bei der Erzeugung. Wenn Sie allerdings im Konstruktor auf andere gemangte Objekte zugreifen wollen, wie bspw. injizierte Objekte mit @EJB oder @Inject funktioniert dies im Konstruktor noch nicht, da zu diesem Zeitpunkt die Objekte noch nicht injiziert wurden.
  21. 21. ANSWER Der Grobe Lifecycle  Container legt Objekt an  Felder bei denen direkt Objekte angelegt werden, werden ausgeführt (bspw. private List<Auftrag> jobs = new ArrayList<>();)  Konstruktor wird aufgerufen (eventueller Code im Konstruktor wird ausgeführt – hier schreibt man daher selten Code aus dem oben beschrieben Problem)  Der Container injiziert gekennzeichnete Objekte  Der Container ruft die annotierte Methode @PostConstruct auf. Wie Sie sehen, haben Sie unterschiedliche Möglichkeiten Werte zu initialisieren. Wenn man dabei den Lifecycle des Objektes grob kennt, kann man für die Klasse dann entsprechend die beste Variante raussuchen.
  22. 22. Question • #1: Warum ist checkPassword() in der Entity definiert und nicht im UserService? • #2: Was ist der Unterschied zwischen Boundary (UserService) und Controller (PWService)? Sind Boundaries Controller, die auf die DB zugreifen? • #3: Wieso verwendet UserService kein begin()/commit() und CreateDummyUser die UserTransaction und nicht die Methoden vom EntityManager? • #4: Für was ist das init() in TestServletTest gut? • #5: Werden wir in der nächsten Vorlesung den Login mit Rest programmieren?!
  23. 23. ANSWER #1: Warum ist checkPassword() in der Entity definiert und nicht im UserService? Hier gibt es unterschiedliche Ansichten, wieviel Logik in einer Entity liegen sollte… Ich bin eher Fan von „dummen Entities“. Das Beispiel checkPassword() haben wir glaube ich initial ganz einfach gehalten und anschließend nicht refactored. Ich gebe Ihnen recht, sollte auch meiner Ansicht nach im UserService sein.
  24. 24. ANSWER #2: Was ist der Unterschied zwischen Boundary (UserService) und Controller (PWService)? Sind Boundaries Controller, die auf die DB zugreifen? ECB Pattern (http://www.cs.sjsu.edu/~pearce/modules/patterns/enterprise/ecb/ecb.htm) Boundary ist die Schnittstelle nach „außen“ (bspw. zum Presentation Layer oder auch zu einem BPMS als Service Orchestrator. Bei der Entwicklung einfach im Boundary anfangen und wenn man das Gefühl hat es wird zu viel für eine Klasse / Methode in Controller auslagern. Der „Meister“ Adam Bien (Java Champion usw…) erklärt dies regelmäßig; auch in seinem letzten Q&A Video. http://www.adam-bien.com/roller/abien/entry/9th_airhacks_tv_q_a Stelle: 15min:20sec Wichtig: eine Boundary ruft nie eine andere Boundary auf! Sonst hätte man eine enge Kopplung. Aus Architektur-Sicht sollte aber ein „decoupling“ ja meist das Ziel sein. Nach Adam Bien ist es aber ok, wenn eine Boundary die Controller Klasse einer anderen Boundary aufruft…
  25. 25. ANSWER #3: Wieso verwendet UserService kein begin()/commit() und CreateDummyUser die UserTransaction und nicht die Methoden vom EntityManager? UserService ist eine EJB (Enterprise Java Bean), genauer eine Stateless Session Bean (SLSB). Erkennt man durch die Annotation @Stateless. SLSB sind per Transaktional – Container Managed Transaction (CMT). Ohne weitere Annotation hat jede public Methode die über die SLSB aufgerufen wird die Transaktion @TransactionAttribute(TransactionAttributeType.REQUIRED). Das heißt, der Container baut um die Methode automatisch ein begin() und ein commit(). Dazu gibt es auch ein paar Folien im EJB Teil. Es geht auch anders bei SLSB: Man kann diese als Bean Managed Transaction (BMT) kennzeichnen, dann muss der Entwickler sich selbst um die Transaktionen kümmern. CreateDummyUser ist ein Servlet und keine SLSB und besist daher kein transaktionales Verhalten. Hier muss sich der Entwickler um Transaktionen mit begin() und commit() selbst kümmern. Aus dem Grund sind SLSB ja recht cool. Spart eine Menge Routinearbeiten…
  26. 26. ANSWER #4: Für was ist das init() in TestServletTest gut? Die Methode init() ist mit der Annotation @Before von jUnit gekennzeichnet. Das heißt die Methode wird vor jedem Test-Case aufgerufen. In der Beispielklasse gibt es nur einen @Test public void shouldWork(). Wären mehrere vorhanden, wird die Methode vor jedem TestCase aufgerufen und kann somit eine allgemein Initalisierung der Testcases vornehmen. Hier würde bspw. soetwas wie „testServlet = new TestServlet();“ gut passen. Jeder Test hätte dann eine neue „saubere“ Instanz der Klasse. Ansonsten steht in init() ja in diesem Fall nichts drin – kann somit auch gelöscht werden.
  27. 27. ANSWER #5: Werden wir in der nächsten Vorlesung den Login mit Rest programmieren?! Wenn dann am SA – für FR steht CDI auf der Agenda. Login ist hierbei allerdings gleich ein etwas komplizierteres Beispiel…. JavaEE hat natürlich auch eine Variante zur Authentifizierung – allerdings haben wir über diese noch gar nicht gesprochen. Ich habe dies bewusst etwas außen vor gelassen, da es hier unterschiedliche Alternativen zum JavaEEWeg gibt (OAuth2.0 bspw., wird von google, twitter, facebook, xing, linkedin verwendet…). Hierzu werde ich das nächste mal etwas mehr erzählen. Generell sind REST Services Zustandslos (Stateless), weshalb hier in der Regel etwas anders verfahren wird als bei einer normalen Webanwendung (hier wird das oft einfach über das Cockie mit der jSessionID gesteuert). Bei einem Stateless Server sollte man die Authentifizierung jedesmal mit geben. Wir werden einige Zugriffe auf unsere Applikation machen – ob wir allerdings eine saubere Authentifizierung in der Zeit hinbekommen kann ich jetzt noch nicht versprechen…

×