Glassfish 3.1: Probleme mit DWR 2 (und mehr)

Geschrieben von everflux am Februar 28th, 2011

Oracle hat heute den Glassfish 3.1 freigegeben – gleichzeitig als Open Source und als Oracle Glassfish Edition. Es gibt eine Menge neues, und dazu gehören auch neue Probleme.

Ich verwende Glassfish schon seit geraumer Zeit um mittels „Continuous Deployment“ für aktuell entwickelte Anwendungen eine separate Umgebung zu haben, in der ich und Kollegen testen können. Das ganze funktioniert mittels eine CI-Servers (Hudson Jenkins in diesem Fall), Maven und einem Deploy Plugin.

Auch mit Glassfish 3.1 funktionierte das Deployment prima – also hier war kein Update von Jenkins oder dem Deploy Plugin erforderlich. Auch die Anwendung startete – jedoch funktionierte nichts. Exceptions über ungültige Sessions gab es, auch Log-Einträge vom hier für Ajax eingesetzten DWR (Direct Web Remoting)

2011-02-28 18:57:13,037 [http-thread-pool-8090(2)] ERROR o.d.dwrp.Batch - A request has been denied as a potential CSRF attack.
2011-02-28 19:03:02,105 [http-thread-pool-8090(5)] ERROR o.d.dwrp.Batch - A request has been denied as a potential CSRF attack.

Dank Firebug etwas schlauem Rumraten und Probieren fand ich dann heraus: Glassfish 3.1 setzt Session Cookies per Default auf „HTTP Only“. Dazu gibt es bereits ein Ticket im Glassfish Tracker: GLASSFISH-15730

Es gibt nun mehrere Möglichkeiten für die nötige Kompatibilität mit Bestandsanwendungen zu sorgen:

Wird man die Anwendung zukünftig immer in einem Servlet 3.0 kompatiblen Container deployen, so kann man in der web.xml das Verhalten umkonfigurieren:

<web-app>
  <session-config>
    <cookie-config>
      <http-only>true</http-only>
    </cookie-config>
  </session-config>
</web-app>

Alternativ kann man bei DWR den CSRF Check deaktivieren, wovon ich jedoch abraten würde:

<servlet>
  <servlet-name>dwr-invoker</servlet-name>
  <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
  <init-param>
    <param-name>crossDomainSessionSecurity</param-name>
    <param-value>false</param-value>
  </init-param>
</servlet>

Die letzte Möglichkeit ist – in diesem Fall – auf DWR 3 umzustellen, hier wurde das Problem grundsätzlich gelöst, so dass nicht mehr per JavaScript auf den Session Cookie zugegriffen werden muss. (Siehe DWR-26) Leider gibt es von DWR 3 bisher noch kein Release, sondern lediglich vorab-Versionen.

Das Problem tritt übrigens auch mit Tomcat 7 auf, und nicht nur mit Glassfish 3.1 – ich frage mich, ob dies Verhalten am Ende sogar in der Servlet 3 Spezifikation vorgegeben ist.
Natürlich betrifft dies nicht ausschließlich DWR, sondern auch andere Anwendungen, die per JavaScript auf den Session Cookie zugreifen wollen/müssen.

Jetty org.eclipse.jetty.io.EofException / Connection closed

Geschrieben von everflux am Februar 17th, 2011

Bei der Umstellung von Jetty 6 zu Jetty 7 gab es (wie bereits geschildert) das eine oder andere an Überraschungsmomenten. So auch bei einem länger laufenden Request ( Fileupload anschließendes Parsen und Datenbank Updates die sich einige Minuten hinziehen können).

Die saubere Lösung wäre hier natürlich dem Nutzer eine Art Fortschritts-Anzeige zu präsentieren. Da die Funktion jedoch so bereits getestet ist, und auch kein Umbau geplant war, sollte es so bleiben. Lediglich Jetty hat hier (mal wieder) einen Strich durch die Rechnung gemacht: Geschlossene Verbindungen die mit org.eclipse.jetty.io.EofException und vielen hässlichen Stacktraces kommentiert wurden. Erst hatte ich die Applikation in Verdacht.

Dann den Browser – macht der Browser vielleicht die Verbindung zu, wird der Socket nur solange wie „keep-alive“ erlaubt ist offen gehalten? Mit etwas wireshark / tcpdump konnte ich dann beweisen: Es war Jetty. Der Server schloss die Verbindung bevor der Prozess fertig war.

Zum Glück kann man aber den idle Timeout von Jetty konfigurieren, das ist die Zeit, in der eine Verbindung ohne Fortschritt fortbestehen darf. (Fortschritt wäre hier ein gesendetes oder empfangenes Byte.) Hier kann man noch gut in die Falle tappen, dass die Zeit in Milisekunden angegeben werden muss – lediglich der verdeckte Hinweis, dass der Wert „grob gesagt“ in den Parameter für Socket.setSoTimeout(int) übersetzt wird, bringt einen hier auf die Spur.

Für das Jetty Maven Plugin sieht das dann so aus:

<configuration>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8080</port>
<maxIdleTime>600000</maxIdleTime> <!-- 10 minutes in milliseconds! -->
<lowResourcesMaxIdleTime>600000</lowResourcesMaxIdleTime>
</connector>
</connectors>
</configuration>

Maven, Jetty und der ExtraClasspath

Geschrieben von everflux am Januar 28th, 2011

Es hat nur wenige Monate gedauert, aber dann konnte ich endlich einen besonders nervigen Fehler finden. Ich verwende Maven (wie fast immer) als Buildsystem und habe ein Projekt, dass Eclipse BIRT verwendet.
BIRT nutzt die Eclipse OSGi Plattform und daher werden beim Start einige Bilbiotheken benötigt. Nun gab es das Problem, dass dies im Tomcat nach einer kleinen Anpassung des Classpath prima funktionierte – nicht jedoch wenn ich das Maven Jetty Plugin verwendet habe. Trotz lt. Dokumentation korrekter Konfiguration über webAppConfig und extraClasspath Elemente.

Die Lösung war dann schließlich nicht mehr das maven-jetty-plugin in Version 6.1.2 sondern das – Achtung – jetty-maven-plugin in Version 7.2.1.v20101111 (die Versionnummer ist kein Witz) zu verwenden. Offenbar ein Jetty Bug – anders kann ich es mir nicht erklären.

Und so sieht dann die vollständige Konfiguration aus, die bei mir dann endlich auch zum Testen schnell und komfortabel funktioniert:

<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <version>7.2.1.v20101111</version>
  <configuration>
    <webAppConfig>
      <extraClasspath>${BIRT_HOME}/lib/engineapi.jar;${BIRT_HOME}/lib/coreapi.jar; \
${BIRT_HOME}/lib/modelapi.jar;${BIRT_HOME}/lib/org.apache.commons.codec_1.3.0.v20100518-1140.jar; \
${BIRT_HOME}/lib/scriptapi.jar</extraClasspath>
    </webAppConfig>
  </configuration>
</plugin>

Maven, Jetty und Reloads: Session persistieren

Geschrieben von everflux am Januar 22nd, 2011

Entwickelt man mit Jetty als Servlet Container, so fällt der im Vergleich zu Glassfish relativ hohe Aufwand für Re-Deployments auf: Startet man Jetty per „mvn jetty:run“ für jedes Deployment erneut, so dauert der Neustart erst mal relativ lange, dazu geht noch die gerade aktive Session verloren. So muss man sich gegebenenfalls nach jeder Änderung bzw. jedem Restart erneut anmelden.
Das kann man relativ einfach ändern: Jetty verfügt über die Möglichkeit die Session zu persistieren – dazu müssen natürlich Session Objekte serialisierbar sein, aber das sollten diese ja sowieso sein. (Stichwort „Session migration“ und „Clustering“)
Leider findet sich auf der Jetty Homepage lediglich eine Anleitung für Jetty 6 – Jetty 7 wird nun von Eclipse weiter entwickelt und damit gehen einige Änderungen einher, für die ich hier eine Beispielkonfiguration habe:

<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.2.1.v20101111</version>
<configuration>
  <webAppConfig>
    <sessionHandler implementation="org.eclipse.jetty.server.session.SessionHandler">
      <sessionManager implementation="org.eclipse.jetty.server.session.HashSessionManager">
      <storeDirectory>${basedir}/target/sessions/</storeDirectory>
    </sessionManager>
  </sessionHandler>
<contextPath>/${project.artifactId}</contextPath>
</webAppConfig>
<!--
<reload>automatic</reload>
<scanIntervalSeconds>2</scanIntervalSeconds>
<scanTargets>
<scanTarget>target/classes/</scanTarget>
</scanTargets>-->
</configuration>
</plugin>

Mit dieser Einstellung werden die Session Daten in dem Order „target/sessions“ persistiert, und man kann bei einem Neustart dort weitermachen, wo man aufgehört hat.

Java Servlet (Spring Controller) auf Root Path mappen

Geschrieben von everflux am Januar 12th, 2011

Nicht immer genuegt es, wenn man ein Servlets auf andere Pfade oder Patterns mappt, manchmal möchte man bereits auf den Context Root ein Servlet mappen. Der übliche Work-Around sieht so aus, dass man bspw. in einer „index.jsp“ einen redirect auf eine tatsächlich einem Servlet zugeordnete URL (über den Pfad oder Datei Extension) macht, das könnte so aussehen:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:redirect url="/myServlet"/>

Das ist aber nicht immer praktikabel – nun soll es darum gehen ein Servlet direkt auf den „/“ Pfad zu mappen – dafür gibt es mehrere Möglichkeiten:

  1. Das Default Servlet ersetzen, dazu wird auf den Root Pfad „/“ in der web.xml ein Mapping angelegt:
    <servlet-mapping>
    <servlet-name>myServlet</servlet-name>
    <url-pattern>/</url-pattern>
    </servlet-mapping>
  2. Ab Servlet Spezifikation kann auch ein Servlet in der welcome-file-list in der web.xml gemappt werden:
    <welcome-file-list>
    <welcome-file>myServlet</welcome-file>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

Im folgenden beschreibe ich die Vor- und Nachteile der verschiedenen Ansätze, und welche Erfahrungen ich mit verschiedenen Web Containern dabei gemacht habe. Weiterlesen »

Netbeans: „package javax.servlet.jsp does not exist“ (cannot find symbol)

Geschrieben von everflux am Januar 7th, 2011

Verwendet man Maven für ein Java JSP Projekt und Netbeans als IDE, so koennen erstaunliche Fehler entstehen: Um mit Servlets zu arbeiten, wird man im Maven die Abhängigkeit auf die Servlet API deklarieren. Da der Webcontainer sich später um die Implementierung der Servlets – und auch das Kompilieren von JSP Seiten – kümmert, gibt man als Scope „provided“ an.

Beispielsweise so:

<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
   <scope>provided</scope>
</dependency>

Damit funktioniert die Entwicklung dann auch prinzipiell – bis auf rote Hinweise und Fehlermeldungen im Netbeans JSP Editor:

„package javax.servlet.jsp does not exist“
(cannot find symbol)

und so weiter und so fort. Bei allen JSP Direktiven, JSP Deklarationen etc. gibt es einen Hinweis darauf, dass Netbeans da etwas im Classpath fehlt. Und Netbeans hat dabei auch Recht – wenn man die JSP API nicht ebenfalls als Projekt Abhängigkeit deklariert. Hier hilft also ein kleiner Zusatz in der Maven pom.xml, der so aussehen könnte:

<dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.1</version>
   <scope>provided</scope>
</dependency>

Hier ist die JSP Version 2.1 passend zur Servlet API 2.5 gewählt. Anschließend einmal „clean and build“ in Netbeans geklickt, und die „package javax.servlet.jsp does not exist“ Fehler sind behoben.

Spring, Hibernate, Glassfish: Memory Leak beim Redeployment?

Geschrieben von everflux am Januar 6th, 2011

Eine in die Jahre gekommene Java Webanwendung, die mit dem Spring Framework (Web mvc) umgesetzt wurde, sollte ein wenig modernisiert werden. Vor allem die Umstellung auf Spring 3 und auf Annotationen basierende Controller war einiges an Migrationsarbeit.

Während des Testens viel mir auf, dass bei jedem Redeployment im Tomcat und im Glassfish 3 der Speicher knapper wurde.  Nichts sonderlich ungewöhnliches bei Java Webanwendungen. Der beste Kandidat für ein sogenanntes Permgen-Leak ist dabei der MySQL Connector (Datenbank Treiber fuer MySQL), wenn dieser mit der Webanwendung im WAR Archiv liegt, und nicht vom Container bereitgestellt wird. Durch die Art, wie sich JDBC Treiber bei Java „anmelden“ können dann Speicherlecks entstehen, wenn die Webanwendung deaktiviert bzw. redeployt wird.

Das besonders nervige an Speicherlecks, die sich auf die Permanent Generation (Permgen) auswirken, ist dass eine einzige Referenz auf den Classloader reicht, um zu verhindern dass der Garbage Collector aufräumt. Das bedeutet, dass man den Erfolg seiner Maßnahmen erst dann sieht, wenn man alle Lecks abgedichtet hat: Eine echte Geduldsprobe. Weiterlesen »

Glassfish remote Monitoring mit VisualVM auf Ubuntu

Geschrieben von everflux am Dezember 20th, 2010

Ubuntu eignet sich hervorragend als Entwicklungsumgebung für Java Anwendungen. Sei es auf dem Desktop oder auf dem Server, bei Ubuntu bekommt man ein aktuelles Sun JDK oder OpenJDK, einen planbaren Releasezyklus. Auch ist ein Unix-artiges Betriebssystem in meinen Augen zum Arbeiten angenehmer als z.B. Windows.

Hat man auf einem entfernten Server, der aber per Netzwerk (oder VPN) erreichbar ist, einen Java Applikationsserver, wie z.B. Glassfish, laufen, so bietet sich JMX zum Monitoring und Management an. Besonders die „VisualVM“ Anwendung macht die Arbeit dabei sehr leicht und übersichtlich. Der Start erfolgt einfach per „jvisualvm“, anschließend können lokale Anwendungen sofort analysiert werden, für entfernte Rechner ist eine JMX Verbindung erforderlich.

Für VisualVM gibt es auch ein Plugin für Glassfish, dies kann über „Tools -> Plugins“ installiert werden. Danach fügt man den entfernten Host hinzu, hier kann man den Hostnamen oder eine IP Adresse eintragen: Weiterlesen »

Oracle Coherence/Fusion Middleware Wettbewerb

Geschrieben von everflux am Juni 23rd, 2010

Oracle Coherence ist eine Datagrid Lösung, mit der sich auf relativ einfache Weise Application-Clustering für gesteigerte Verfügbarkeit oder Lastskalierung realisieren lässt. (Oracle Coherence ist zum kostenlosen Download auf oracle.com/../coherence verfügbar, für den produktiven Einsatz sind ggf. kostenpflichtige Lizensierungen erforderlich.)
Mit einer Datagrid Lösung lassen sich Rechenaufgaben verteilen, um ein Computing-Grid aufzubauen, hauptsächlich findet Coherence jedoch seinen Einsatz beim Clustering von Anwendungen wie z.B. dem Confluence Wiki von Atlassian, oder auch wenn es um verteiltes Caching von Daten geht. (Ähnlich wie memcached, dass im PHP Umfeld besonders populär ist.) Weiterlesen »

Oracle veröffentlicht Netbeans 6.9

Geschrieben von everflux am Juni 16th, 2010

Netbeans ist nun in der Version 6.9 von Oracle freigegeben worden. Die Entwicklungsumgebung für Java, PHP, JavaScript, Groovy, Scala, … wird von Oracle zusammen mit der OpenSource Community entwickelt. Das nun veröffentlichte Netbeans 6.9 enthält viele Neuerungen. Für PHP Entwickler besonders interessant ist die Unterstützung des Zend Framework in der aktuellen Version. Weiterlesen »


http://everflux.de/
Copyright © 2007, 2008 everflux. Alle Rechte vorbehalten. All rights reserved.