Arndt Schönbergs Weblog

Mittwoch Mai 15, 2019

JSF Converter mit EJB Injection – JSF 2.3

Gerade für Konverter war es schmerzlich, dass ein Injizieren von EJBs und anderen CDI Beans nicht möglich war. Mit JSF 2.3 kam nun endlich das notwendige Feature (wie auch für Validator und Behavior).

https://javaserverfaces.github.io/whats-new-in-jsf23.html

beschreibt die neuen Möglichkeiten und auch dass das Attribut „managed = true“ gesetzt werden muss.

Verwendet man nun ausschließlich diese Informationen und versucht eine EJB in einen @FacesConverter zu injizieren, erhält man eine NPE, da das Injizieren nicht funktioniert. Folgende weiteren Bedingungen müssen erfüllt sein:

Es müssen JSF Bibliotheken größer gleich Version 2.3. verwendet werden. Prüft diese beim Starten des Servers in den Logs. Gegebenenfalls wurde die Mojarra Implementierung explizit in der web.xml gesetzt und muss angepasst werden.

Es muss ein beans.xml Datei existieren, in der

 
bean-discovery-mode="all" 
gesetzt ist (Achtung annotated ist hier nicht ausreichend).
 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
   bean-discovery-mode="all" version="2.0">
</beans>
Die faces-config.xml muss die Version 2.3 vorweisen
 
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.3"
          xmlns="http://xmlns.jcp.org/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
                    http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd">
    ....
</faces-config>
Der letzte und eventuell unerwartetste Schritt ist eine Konfiguration über eine Annotation, die einmal im Projekt existieren muss.
 
package de.schoeso.jsf;

import javax.faces.annotation.FacesConfig;
import javax.faces.annotation.FacesConfig.Version;

// Aktiviert CDI build-in Beans
@FacesConfig(
    version = Version.JSF_2_3
)
public class ConfigBean {

    /** Konstruktor */
    public ConfigBean() {
    }

}
Erst all diese Einstellungen führen zum Erfolgt. Als verwöhnter JEE Nutzer hätte man sich gewünscht, dass dies wie andere Funktionen von JEE einfacher zu verwenden ist ... aber man soll nicht klagen. Eventuell tut sich da ja noch etwas.

Bis zum nächsten Mal

Arndt

Dienstag Mär 26, 2019

HTTP Remote Zugriff Wildfly 16

In Version 16 (ohne es geprüft zu haben, sollte der hier beschriebene Zugriff für alle Wildfly Versionen ab Version 11 gelten) hat sich der HTTP-Zugriff stark vereinfacht. Dafür haben meine Recherchen zu einem ordentlichen SSL Zugriff wenig ergeben. Hier scheint die Dokumentation noch nicht den üblichen Stand zu haben ... aber auch hierzu werde ich im nächsten Post eine detaillierte Beschreibung erstellen.

Properties

In Version 16 sind die notwendigen Properties für den HTTP-Zugriff stark vereinfacht worden. Es wird die INITIAL_CONTEXT_FACTORY gesetzt und das Protokoll (hier: http-remoting) und die HTTP-Adresse und der Port des Servers angegeben.
 
final Properties jndiProperties = new Properties ();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY,  "org.wildfly.naming.client.WildFlyInitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL,"http-remoting://" + ipAddress + ":8080");

Zugriff

Der Zugriff erfolgt dann über ein einfaches lookup
 
final Context context = new InitialContext(jndiProperties);
…
return (T) context.lookup();
Diese Variante des Remote-Zugriffs enthält keine Form der Absicherung. Es gibt keine Verschlüsselung und keine Nutzer Authentifizierung. Man kann also sagen, sie sollte nur in Testumgebungen verwendet werden!!!

Und was ist mit einem sicheren Zugriff?

Hierzu mehr im folgenden Post ...

Donnerstag Sep 13, 2018

Spooky Exceptions (11) - ... javax.ejb.EJBException: WFLYEJB0442: Unexpected Error

Umgebung

  • Wildfly 13
  • EE7
  • Eclipselink

Situation

Bei dem Aufruf einer JPA Query wird folgende Exception geworfen
 
   ... javax.ejb.EJBException: WFLYEJB0442: Unexpected Error
   ...
   Caused by: java.lang.StackOverflowError
   at org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.getRoot(AbstractExpression.java:530)
   at org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.getRoot(AbstractExpression.java:530)
   at org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.getRoot(AbstractExpression.java:530)
    ...

Lösung

Ursache dieser Exception ist eine lange Kette von WHERE Bedingungen (ca 2250) in einer JPQL Abfrage, die über Parameter befüllt werden. Es scheint hier Grenzen in der Verarbeitungsfähigkeit zu geben. Solche Anfragen müssen in Einzelanfragen aufgebrochen oder umformuliert werden.

Freitag Jul 13, 2018

Spooky Exceptions (10) - An exception occurred while creating a query in EntityManager

Umgebung

  • Wildfly 13
  • EE7
  • Eclipselink

Situation

Bei dem Aufruf einer JPA Query kommt eine Exception
 
  2018-06-22 12:45:43,615 ERROR [org.jboss.as.ejb3.invocation] (default task-1) WFLYEJB0034: 
  EJB Invocation failed on component DataPrivacyStatementAcceptanceFacade
  for method public abstract de.schoeso.festival.ejb.mde.DataPrivacyStatementAcceptanceList 
  de.schoeso.festival.ejb.mde.facade.DataPrivacyStatementAcceptanceFacadeLocal.findByVariousParameters(): javax.ejb.EJBException: 
  java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:  
  Exception Description: Problem compiling [SELECT x FROM DataPrivacyStatementAcceptance x]. 
  [14, 44] The abstract schema type 'DataPrivacyStatementAcceptance' is unknown.
	at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInNoTx(CMTTxInterceptor.java:223)
	at org.jboss.as.ejb3.tx.CMTTxInterceptor.supports(CMTTxInterceptor.java:418)

Lösung

Ursache dieses Kompilierungsproblems und des fehlenden "abstract schema type" war, dass die Entität nicht in der persistence.xml eingetragen war (bzw. nicht erkannt wurde).

Spooky (missing) Exceptions (9) - Objekt wird vom (Eclipse) JPA Provider nicht in die Datenbank geschrieben

Umgebung

  • Wildfly 10
  • EE7
  • Eclipselink

Situation

Ein Subobjekt einer Entität (OneToOne), das über cascade = CascadeType.ALL angebunden ist, wird bei merge nicht persistiert.

Analyse

In diesem Fall wurde das Objekt nicht im Oberobjekt instanziiert
 
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "repairWarranty", fetch = FetchType.EAGER)
    private StateChange stateChange = null;
  • Bei dem ersten Zugriff auf das Objekt über den getter wurde das Objekt angelegt
  • In einer Livecycle Methode @PostPersist wurde auf das Objekt zum ersten mal zugegriffen
Wenn ein abhägiges Objekt erst in einer Livecycle Methode @PostPersist instanziiert wird, erkennt aktuell (Version 2.6.x) der (Eclipselink) JPA Provider nicht, dass dieses Objekt gespeichert werden muss. Auch wenn ohne ein refresh des Oberobjekts nochmals versucht wird ein merge durchzuführen, werden die Daten nicht in die Datenbank geschrieben (sind aber im Objekt enthalten, was das Debugging deutlich erschwert).

Lösung

Entweder die (indirekte) Instanziierung in den Livecycle Methoden vermeiden oder die Objekte direkt anlegen
 
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "repairWarranty", fetch = FetchType.EAGER)
    private StateChange stateChange = new StateChange ();

Calendar

Feeds

Search

Links

Navigation