This blog has moved to
http://blog.matthias-reining.com

Die bestehenden Artikel bleiben vorerst alle bei blogspot. Neue Artikel veröffentliche ich allerdings nur noch auf http://blog.matthias-reining.com

Dienstag, 27. Dezember 2011

javax.el.ELException: /dummy.xhtml: The class 'de.Dummy$Proxy$_$$_WeldClientProxy' does not have the property 'dummy'... Primeface namespaces

Wenn die Fehlermeldung

javax.el.ELException: /dummy.xhtml: The class 'de.Dummy$Proxy$_$$_WeldClientProxy' does not have the property 'dummy’

auftaucht, kann dies ggf. an Primefaces liegen (falls ihr es überhaupt eingebunden habt…)

Beim Wechsel von Primefaces 2 auf Primefaces 3  ist dies bei mir aufgetreten. Genauer gesagt bei dieser Version:

<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>3.0.RC1</version>

Leider war die Fehlermeldung bzw. der Stacktrace nicht sonderlich aufschlussreich.

Die Primefaces-Namespaces haben sich geändert, was den Fehler verursacht:

Alt: xmlns:p="http://primefaces.prime.com.tr/ui"

Neu (>=3.0RC1): xmlns:p="http://primefaces.org/ui"

Freitag, 2. Dezember 2011

eclipse - JEE Web Projekt mit exploded JAR-File unter WEB-INF\lib ?!?


Wenn ich in eclipse ein Maven JEE Web Projekt  habe (maven archetype: jboss-javaee6-webapp version: 7.0.2.CR) , dass eine dependency auf eine eclipse Maven EJB-JAR Projekt hat (ejb-javaee6 version:1.5), bekomme ich folgende Fehlermeldungen im JBoss AS 7:

01:07:52,533 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-3) MSC00001: Failed to start service jboss.deployment.unit."is-pm-test.war".STRUCTURE: org.jboss.msc.service.StartException in service jboss.deployment.unit."is-pm-test.war".STRUCTURE: Failed to process phase STRUCTURE of deployment "is-pm-test.war"
       at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:121)
       at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1824)
       at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1759)
       at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) [:1.6.0_20]
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [:1.6.0_20]
       at java.lang.Thread.run(Unknown Source) [:1.6.0_20]
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: org.jboss.as.server.deployment.DeploymentUnitProcessingException: failed to process "/D:/java-server/jboss/jboss-as-7.0.2.Final/standalone/deployments/is-pm-test.war/WEB-INF/lib/is-temporaldata-0.0.1-SNAPSHOT.jar"
       at org.jboss.as.web.deployment.WarStructureDeploymentProcessor.deploy(WarStructureDeploymentProcessor.java:118)
       at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:115)
       ... 5 more
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: failed to process "/D:/java-server/jboss/jboss-as-7.0.2.Final/standalone/deployments/is-pm-test.war/WEB-INF/lib/is-tmp-0.0.1-SNAPSHOT.jar"
       at org.jboss.as.web.deployment.WarStructureDeploymentProcessor.createWebInfLibResources(WarStructureDeploymentProcessor.java:173)
       at org.jboss.as.web.deployment.WarStructureDeploymentProcessor.createResourceRoots(WarStructureDeploymentProcessor.java:151)
       at org.jboss.as.web.deployment.WarStructureDeploymentProcessor.deploy(WarStructureDeploymentProcessor.java:112)
       ... 6 more
Caused by: java.util.zip.ZipException: error in opening zip file
       at java.util.zip.ZipFile.open(Native Method) [:1.6.0_20]
       at java.util.zip.ZipFile.<init>(Unknown Source) [:1.6.0_20]
       at java.util.jar.JarFile.<init>(Unknown Source) [:1.6.0_20]
       at java.util.jar.JarFile.<init>(Unknown Source) [:1.6.0_20]
       at org.jboss.vfs.spi.JavaZipFileSystem.<init>(JavaZipFileSystem.java:95)
       at org.jboss.vfs.spi.JavaZipFileSystem.<init>(JavaZipFileSystem.java:81)
       at org.jboss.vfs.VFS.mountZip(VFS.java:408)
       at org.jboss.vfs.VFS.mountZip(VFS.java:434)
       at org.jboss.as.web.deployment.WarStructureDeploymentProcessor.createWebInfLibResources(WarStructureDeploymentProcessor.java:168)
       ... 8 more


Ursache:
Das eclipse Maven Plugin deployed zum einem das WAR Projekt exploded (was sehr gut ist!). Weiterhin deployed es aber auch alle abhängigen JAR Dateien unter WEB-INF\lib (mvn dependencies) exploded, die auf geöffneten eclipse Projekten stammen.

Der App Server kann damit verständlicherweise nicht umgehen (class files unter WEB-INF\lib, wo gibt’s denn sowas?).

Abhilfe:
Dieses Verhalten kann verhindert werden, in dem man in den abhängigen Projekten folgende Einstellung vornimmt:

Project Properties (des EJB-JAR eclipse Projektes) -> Project Facets -> Utility Module aktivieren.

Anschließend warden die entsprechenden JAR Dependencies nicht mehr exploded abgelegt J

Mittwoch, 23. November 2011

Internationalisierung und Datenformate

Internationalisierung und Datenformate

Der folgende Artikel ist der Rohentwurf für einen Magazin-Artikel. 

Babylon war gestern!?

Verschiedene Sprachen gab es schon immer! Bereits im Alte Testament hatte ein Sprachgewirr den Stopp des Turmbaus zu Babel zur Folge. Diese Zeiten sind dank Normierungsgremien schon lange vorbei – allerdings beherbergen unterschiedliche Sprachen oft auch unterschiedliche Darstellungsformate was bei einer Konvertierung wiederrum auch heutzutage noch zu den unterschiedlichsten Fehlern führen kann.
Neben der eigentliche Sprache unterscheiden sich auch Datenformate (Zahlen, Uhrzeiten, Datum, …). Hier gibt es unterschiedliche Formate und jedes Land macht es irgendwie anders… Es ist noch nicht mal gesagt, dass wen die gleiche Sprache gesprochen wird, dass dann die Formate gleich sind.
Ein Datum im englischsprachigen Kanada schaut anders aus als in den USA. So wird bspw. der 14. November 2011 in kurzer Form in Kanada als 14/11/2011 geschrieben und in den USA als 11/14/2011 (Monat und Tage genau andersherum).
Es ist durchaus ganz interessant, zu schauen wie unterschiedlich hier die Formate zum Teil sind (dies geht sogar so weit, dass unterschieden wird an welchem Tag die Woche beginnt)
An einem Windows-PC kann man hier ganz einfach recherchieren:
Windows à Systemsteuerung à Region und Sprache:


Noch detaillierte Informationen bekommt man zu den jeweiligen Länderspezifikas wenn sich die „Weiteren Einstellungen“ anschaut.

Anbei eine kurze Aufzählung von Elementen die sich je Ländereinstellung alleine bei den Zahlenformaten unterscheiden können:


Zahlen
Beispiel 1 (de)
Beispiel 2
Dezimaltrennzeichen
,
.         [USA][fs1] [mre2] 
Anzahl der Dezimalstellen
2
2        [USA][fs3] [mre4] 
Symbol für Zifferngruppierung
.
<blank>       [Frankreich] 
Zifferngruppierung
123.456.789
123456.789  [Grönland: einmalige Gruppierung]
Negatives Vorzeichen
-
-         [USA][fs5] [mre6] 
Format für negative Zahlen
-1,1
1.1-    [persisch, minus nachgestellt]
Führende Null anzeigen
0,7
.7 [Thai]
Listentrennzeichen
;
,         [USA]
Maßsysteme
Metrisch, z.B. Zentimeter
US-Maße, z.B. inch         [USA]



Neben den Zahlen gibt es noch weitere Kategorien wie etwa Währung, Uhrzeit, Datum und Sortierung die sich je nach Land unterscheiden können.
Nach dieser kleinen Aufzählung von Besonderheiten überrascht es vermutlich auch nicht, dass dies in der IT manchmal zu Problemen führen kann.

 

Interpretation

Sind die richtigen Werte erst mal in einem IT-System wie einer Datenbank gelandet, hat man schon einen Großteil richtig gemacht. Eine Datenbank verwaltet Zahlen, Uhrzeiten und Datumswerte in einer internen Darstellung.
Die größte Fehlerquelle tritt daher meist bei der Konvertierung der Werte in das interne Format auf. Die entsprechenden Werte müssen von den Systemen korrekt interpretiert werden.

Im folgendem einige Szenarien bei denen es bei der Interpretation von Werten oft zu Problemen kommen kann:

Datenerfassung auf Webseiten / Spracheinstellungen
Ein Webbrowser kann ebenfalls eigene Spracheinstellungen haben.
Dies ist besonders dann interessant wenn eine Webanwendung in mehrere Sprachen verfügbar sein soll.
Die eingestellte Länderkennung wird dann an den Server mitgegeben und ermöglich es bestehenden Web Frameworks eine Konvertierung vorzunehmen in die entsprechenden Datentypen (Number, Date, String).
Dies klappt solange gut, solange man auch mit den korrekten Datentypen arbeitet. Wird ein Datumswert in einem Textfeld (String) gespeichert, kann ein Framework hier nicht mehr unterstützen. Eine anschließende manuelle Konvertierung ist oft schwierig oder sogar unmöglich.
àsaubere Datenformate, nichts selber machen; die meisten Frameworks (Struts, JSF, ASP.NET) können / besitzen NLS (i18n).

CSV - Importdateien
Häufig werden CSV-Dateien aus Excel zum Import in IT Systeme verwendet.
Auch dies kann zu Problemen führen.
Wenn man eine CSV Datei mit einem Texteditor ansieht, sieht man das dort meist Strichpunkte als Trennzeichen verwendet werden und keine Kommas. Dies liegt daran, dass in Nordeuropa als Listentrennzeichen ein Strichpunkt verwendet wird, in den USA dagegen ein Komma.
Dies hat zur Folge, dass bei der Erstellung einer CSV Datei aus Excel heraus die Ländereinstellungen des Betriebssystems abgefragt werden. Werden diese nicht überschrieben kann daher eine CSV Datei auf einem Rechner mit deutschen Einstellungen anders aussehen als auf einem amerikanischen Rechner.
Wenn die CSV Datei in ein System hochgeladen wird, kann man das entsprechende Format ggf. noch an der Ländereinstellung des Clients erkennen. Falls ein System allerdings eine CSV Schnittstelle hat, empfiehlt es sich das Format im Vorfeld fest mit allen Beteiligten  zu vereinbaren.
àNicht die Defaulteinstellung des Listentrenners nehmen, sondern ein festes Format dafür vereinbaren.
Das gleiche Problematik beim Import tritt nicht nur bei den Listentrennern ein sondern auch bei den Datentypen einzelner Spalten (Zahlen, Datum). Hier empfiehlt es sich wiederrum das genau Format mit allen beteiligten im Vorfeld zu definieren!

Batchverarbeitung
Bei der Batchverarbeitung treten die gleiche Probleme auf wie bereits oben beschrieben, nur dass diese manchmal schwerer zu testen sind.
Die meisten Programmiersprachen konvertieren Zahlen und Datumswerte mit den Defaulteinstellungen des Systems auf dem sie gerade laufen. Im Client-Bereich ist dies auch sehr nützlich; läuft das Programm allerdings auf dem Server kann das zu Problemen führen.
Leider kommt es immer wieder vor, dass sich die lokalen Einstellungen nicht von denen auf der Stagingumgebung unterscheiden. Hier funktioniert dann immer noch alles…
Wenn sich dann allerdings die Stagingumgebung von der Produktion im Bereich der Region- und Ländereinstellungen unterscheidet, kann es zu ungewünschten Problemen führen.
Aufgrund von mangelnden Serverresourcen kommt der Fall, dass die Testumgebung nicht identisch mit der Produktionsumgebung ist, in der Praxis leider öfters vor.
àNicht die Defaulteinstellung nehmen, sondern ein festes Format. bspw. immer mit der Angabe „de“


Summary

Mit Tests können natürlich auch hier viele Fehler vermieden werden. Aufgrund von unterschiedlichen Default-Einstellungen der Test- und Produktivserver kann es aber trotzdem immer wieder zu unerwünschten Formatproblemen kommen.
Problem ist erkannt und in der Java Welt versucht man diese Problematik ein bisschen zu bekämpfen mit dem neuen Datumstyp „Joda-Time“.
Letztendlich ist das Themenfeld Zahlen- und Datuminterpretation immer ein Fehlerpotential, das man nur mit entsprechenden Know How sauber bewältigen kann.


Donnerstag, 7. Juli 2011

Maven, WTP und der ClassPath

Verwendet man das m2eclipse Plugin bei der Webentwicklung in eclipse (WTP – Web Tools Platform), tritt leider ein unerwünschtes Verhalten auf…

Eclipse kennt nur einen ClassPath.
Schlimm genug.
Leider werden die, in Maven als provided gekennzeichnet Libraries, auch vom WTP Plugin in das WEB-INF\lib Verzeichnis kopiert/deployed (siehe http://jira.codehaus.org/browse/MNGECLIPSE-714).

Bei vielen Libraries ist dies nicht weiter schlimm. Bei einigen anderen verhindert dies dagegen die korrekte Funktionsweise des Tomcats.

In meinem Beispiel habe ich in dem kompletten Tomcat einen Transaktionsmanager „gegeben“ (BTM). Dieser hängt sich unter anderem in die Datasoure Definition aus der server.xml.

Als common-lib wird hier bspw. jta-1.1.jar benötigt (liegt unter <CATALINA_HOME>\lib.
Ist diese Library dann nochmal in der eigentlichen Webapplikation unter WEB-INF\lib funktioniert BTM nicht mehr korrekt und die Applikation kann auf keine DB Resourcen zugreifen.

Folgender „Hack“ verschafft Abhilfe:

pom.xml:
       <profiles>
             <profile>
                    <!-- Da eclipse keine Unterscheidung beim Classpath kennt und das m2eclipse
                           hier auch keine Unterstützung bietet (http://jira.codehaus.org/browse/MNGECLIPSE-714
                           -Timestamp:06.07.2011), werden Libraries die provided sind per WTP innerhalb
                           von eclipse immer in das WEB-INF\lib Verzeichnis kopiert. Mit Hilfe des Profiles
                           wird in im Normalfall (profile: default) die provided Libraries von maven
                           richtig gehandelt. Falls man sich in der eclipse Umgebung befindet kommen
                           diese nicht in den Web-App Classpath. Die kann über ein Property sichergestellt
                           werden. Das einzigste Property das in Eclipse beim Start gesetzt wird, ist
                           in den aktuellen eclipse Versionen osgi.requiredJavaVersion. Anhand von diesem
                           wird daher das Profile gewählt -->
                    <id>eclipse-env</id>
                    <activation>
                           <property>
                                  <name>osgi.requiredJavaVersion</name>
                                  <value>1.5</value>
                           </property>

                    </activation>
             </profile>
             <profile>
                    <id>default</id>
                    <activation>
                           <activeByDefault>true</activeByDefault>
                    </activation>
                    <dependencies>
                           <dependency>
                                  <groupId>org.apache.tomcat</groupId>
                                  <artifactId>tomcat-servlet-api</artifactId>
                                  <version>7.0.16</version>
                                  <scope>provided</scope>
                           </dependency>

                           <dependency>
                                  <groupId>org.codehaus.btm</groupId>
                                  <artifactId>btm</artifactId>
                                  <version>2.1.1</version>
                                  <scope>provided</scope>
                           </dependency>
                           <dependency>
                                  <groupId>javax.transaction</groupId>
                                  <artifactId>jta</artifactId>
                                  <version>1.1</version>
                                  <scope>provided</scope>
                           </dependency>
                    </dependencies>
             </profile>
       </profiles>

Mit Hilfe des neuen Maven Profiles „default“ werden die provided Libraries per Default geladen (activatedByDefault=true).
Innerhalb von eclipse greift aber das Profile „eclipse-dev“. Das Ganze wird anhand des java Paramters osgi.requiredJavaVersion ermittelt. Dieser Paramter wird beim Start von eclipse mitgegeben und ist daher bei der direkten Verwendung von Maven innerhalb von eclipse immer vorhanden.

So einen Parameter setzt ein „normaler“ Web-Entwicklung normalerweise ja nicht, so dass es hier zu keinerlei Konflikten kommen sollte ;-)

Mit diesem „Hack“ tauchen die provided Libraries nicht mehr im eclipse Class-Path auf und werden somit auch nicht nach WEB-INF\lib deployed.

J