Archiv für die Kategorie ‘Allgemeines’

JDK Development Tools

Freitag, 01. Oktober 2010

Vor einigen Tagen bemerkte ich ein ungewöhnliches Verhalten von einer unserer Tomcat Serverinstanzen. Der Server schien normal zu laufen, aber ein Kern der CPU wurde bereits seit einigen Minuten zu 100% belastet. Die Anwendung war ganz normal erreichbar und auch in der Logausgabe waren keine Unregelmäßigkeiten zu finden. Eine Kopie der Produktivinstanz lief in der Testumgebung problemlos. Es handelte sich also um ein Problem, das erst zur Laufzeit entsteht und nicht mit dem Datenbestand o.ä. zusammenhängt. Ein Neustart würde das Problem wohl beheben – aber tritt es dann eventuell wieder auf? Hat ggf. ein Anwender nur einen sehr umfangreichen Report gestartet und der Server braucht für die Verarbeitung einfach sehr lange oder handelt es sich um einen Bug in der Software?

Für mich stellte sich also die Frage, wie ich nun herausfinde, was der Server dort gerade macht. Ein Neustart kam aber nicht in Frage, da das Problem dann verschwinden würde und eine Fehleranalyse unmöglich wäre.

Eine Recherche im Internet führte mich schneller als erwartet zum Ziel. Das aktuelle Java SDK bringt eine ganze Reihe von Tools zur Überwachung von Javaprozessen mit. Eines dieser Tools nennt sich jstack und zeigt mir den aktuellen Stack aller Threads innerhalb eines Prozesses an. Das schuldige MemoryLeak war schnell gefunden und gefixed. Alles was ich brauchte war also bereits auf dem Server installiert.

Ein Blick auf die JDK Develoment Tools lohnt sich also in jedem Fall. Gerade wenn man keine Möglichkeit mehr hat, ein Monitoring Tool zu installieren oder man sich nicht sicher ist, was da gerade läuft, können einem diese (meist schon vorhanden) Tools weiterhelfen.

(jstack ist wohl leider noch nicht im Windows JDK enthalten. Alternativ kann man dort aber die grafische jconsole verwenden. Auch diese ist im JDK enthalten.)


Felix Breske


Javascript im href von HTML-Links

Donnerstag, 22. Juli 2010

Wer Probleme damit hat, browserkompatibel auf clicks bei Links zu reagieren, kann dies mit Hilfe des Schlüsselwortes ‘javascript:’ zu Beginn des href-Attributwertes verwirklichen.

Bsp:

<a href="javascript:myFunction();">Ein Link</a>

Angenommen, die Funktion myFunction() sieht nun beispielsweise so aus:

function myFunction() {
alert("Hallo!");
return false;
}

Dann wird die Seite, die den Link beinhaltet, gelöscht und eine neue Seite angezeigt, auf der lediglich das Wort ‘false’ steht. Das liegt daran, dass das Ergebnis des Javascripts in eine neue Seite gerendert wird.

Wichtig ist also, dass der Rückgabewert von myFunction undefined ist, wenn man möchte, dass die ursprüngliche Seite erhalten bleibt.


Christian Borkowski


PostgresSQL String Konstanten / Dateien namens “con.xyz”

Montag, 05. Juli 2010

Mein Ziel war es, korrupte javascript-RegEx Ausdrücke durch neue Ausdrücke zu ersetzen. Das Problem dabei waren die Zeichen, die ein Escaping benötigen, um den String(character varying) in eine Postgres DB einfügen zu können. Bei recht komplexen Ausdrücken eine umständliche Arbeit, die Zeichen einzeln zu “escapen”. Das ganze kann man sich aber folgendermaßen ersparen:

UPDATE testtabelle
SET textfeld = $stringconstant$Text mit vielen /^'\" $$stringconstant$
WHERE id = 4711;

Das ganze nennt sich “Dollar-Quoted String Constants”. Der String wird also zwischen zwei voranführenden und zwei endenden Dollarzeichen verpackt: $$ SomeCharacters/\^’#” $$ . Zwischen den Dollarzeichen kann, wie im obigen Beispiel, ein Tagname angegeben werden, um so z.B. auch verschachtelte Strukturen zu ermöglichen.

$outerTag$
someText $innerTag$ otherText $innerTag$
$outerTag$

Ein ganz anderes Thema…

Bei dem Versuch eine csv-Datei aus Java heraus anzulegen, flog eine Exception, nach ein bischen Verzweiflung und “googeln” kam heraus, dass der Name der Datei con.csv das Problem verursachte.
WindowsXP verbietet das Anlegen jeglicher Dateien mit Namen “con” gefolgt von einem Punkt oder einem Leerzeichen. Ärgerlich aber nicht umgehbar, angeblich ein Überbleibsel aus den alten MS-Dos Zeiten.


Sven Seiler


Zeitmessung mit Spring AOP

Donnerstag, 24. Juni 2010

Trifft man bei der Entwicklung einer Anwendung auf Performanceprobleme, reicht es meist aus, die verantwortlichen Codebereiche aufzuspüren, um dann den Fehler/das Problem zu beheben. Jedoch gestaltet sich das Auffinden der betroffenen Codestellen meist als schwierig oder langwierig. In jede verdächtige Methode Log-Ausgaben mit der Zeitmessung zu schreiben, wäre unsauber. Mit Spring ist die einfachste Lösung, einen Interceptor zu konfigurieren, der die Methodenaufrufe unterbricht und die Zeitmessung ins Log schreibt.

Als erstes definieren wir einen Advice (Interceptor-Bean), die Implementierung bringt Spring schon mit.

<bean id="timingLogger" 
class="org.springframework.aop.interceptor.PerformanceMonitorInterceptor" />

Als zweiten Schritt können wir mit der AOP Konfiguration festlegen, welche Methodenaufrufe protokolliert werden sollen, damit die Log-Datei übersichtlich bleibt. Folgend zum Beispiel alle public-Methoden der Spring-Beans im Paket service und allen Unterpaketen:

<aop:config>
   <aop:pointcut id="services" expression="execution(* de.myApp.service..*.*(..))" />
   <aop:advisor advice-ref="timingLogger" pointcut-ref="services" />
</aop:config>

Für das Definieren der korrekten pointcut-expression hilft die ausführliche Spring Dokumentation (7.2.3 Declaring a pointcut, Version 3).
Damit das Ergebnis in den Logs auftaucht, sollte für diesen Interceptor der Log-Level auf TRACE stehen:

log4j.logger.org.springframework.aop.interceptor.PerformanceMonitorInterceptor=TRACE

Die Ausgabe sieht dann zum Beispiel so aus:

2010-06-24 09:06:53,109 TRACE PerformanceMonitorInterceptor:64 - StopWatch 'de.myApp.service.MyService.methodName': running time (millis) = 1813

Für eine erste Analyse ist diesen Vorgehen hilfreich, will man jedoch aggregierte Werte über einen Zeitraum bekommen, bietet sich zum Beispiel Perf4J an. Mit diesem Tool lassen sich aggregierte Messwerte (Min, Max, Durchschnitt, Anzahl) in eine extra Logdatei schreiben.

Es besteht aber auch die Möglichkeit einer einfachen eigenen Implementierung:

public class TimingLoggingInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        StopWatch sw = new StopWatch();
        sw.start();
        Object returnValue = invocation.proceed();
        sw.stop();
        System.out.println(
            invocation.getClass().getSimpleName() + "#" + 
            invocation.getMethod().getName() + ": " +
            sw.getTotalTimeMillis());
        return returnValue;
    }
}

Nun muss nur noch der Wert der Spring-StopWatch gespeichert werden. Diese eigene Lösung ist besonders interessant, wenn nur unter bestimmten Bedingungen die Werte geloggt werden sollen, zum Beispiel wenn die Laufzeit eine definierte Obergrenze überschreitet.


Jan Kuenstler