Was ist ein class path/class loader in Tomcat?

07.04.2017

Tomcat installiert viele class loaders (eine Klasse, die java.lang.ClassLoader) implementiert, damit Webapplikationen, die auf dem Tomcat laufen, Zugriff zu verschiedenen Klassen und Ressourcen haben.

Ein Klassenpfad (class path) ist ein Argument, welches der Java Virtual Machine mitteilt, wo es die Klassen und Pakete findet, welches es für die Ausführung der Applikation benötigt. Diese Aufgabe hat man bewusst vom eigentlichen Java Programm separiert, damit man die Einstellungen von aussen machen und so die Applikation auf verschiedenen Systemen zum laufen bringen kann.

Eltern-Kind Beziehung

In Java sind class loaders in einer Eltern-Kind Beziehung (parent-child). Wenn ein class loader eine Klasse laden muss, dann gibt er diesen Auftrag normalerweise zuerst an den parent class loader weiter. Nur wenn dieser die Klasse nicht findet, schaut er in seinem eigenen Repository.

Die verschiedenen Stufen bei Tomcat sind:

Bootstrap -> System -> Common -> Webapplikationen

Wobei die Eltern jeweils links und die Kinder rechts sind.

Wie verwendet Tomcat den Klassenpfad?

Tomcat will es einem grundsätzlich so einfach wie möglich machen. Wenn Tomcat gestartet wird, ignoriert Tomcat erst mal knallhart die Java classpath Umgebungsvariable, wo Abhängigkeiten normalerweise drinstehen. Stattdessen macht Tomcat seine eigenen Klassenpfade, wenn er den System class loader erstellt.

Deklariert man also einen Klassenpfad in der Umgebungsvariable, muss man sich nicht wundern, wenn Tomcat diese beim Starten überschrieben hat.

Folgende Schritte macht Tomcat beim Starten:
1. Die JVM ladet zuerst die Java Bibliotheken und die Umgebungsvariablen wie JAVA_HOME.
2. Tomcat erstellt seine classloader, welche alle Klassen und JAR Dateien in den beiden Ordner WEB-INF/classed und WEB-INF/lib ladet. Diese Ressourcen sind dabei nur sichtbar von den Webapplikationen, welche diese laden.
3. Der „Common class loader“ von Tomcat ladet alle Klassen und JAR Dateien in $CATALINA_HOME/lib. Diese Ressourcen sieht dann der Tomcat plus alle Applikationen, die darauf laufen.

Und wenn ich die Einstellungen ändern will?

Zum Glück sind die Einstellungen von Tomcat nicht hartcodiert, sondern werden von Catalina’s zentraler Optionsdatei geladen. Diese liegt in $CATALINA_HOME/conf/catalina.properties.

In dieser Datei kann man, wenn dies nötig ist, externe Repositories angeben, welche geladen werden sollen. Dafür kann etwa der shared loader verwendet werden. Die Klassen werden dabei vom shared loader am Ende des Startprozesses geladen, also auch nach dem Common loader.

Um etwa eine externe JAR Datei als Klassen Repository zu verwenden, trage beim Shared Loader ein:

shared.loader=file:/pfad/zur/datei/meinJar.jar

Eine gute Anwendung des Shared Loaders kann man in meinem Artikel Zwei WARs kommunizieren auf einem Tomcat nachlesen.

Was ist der Java Klassenpfad?

09.03.2017

Programmiert man in Java, gibt man am Anfang jeder Klasse an, zu welchem Paket eine Klasse gehört.

import ch.studiprojekt.SuperAlgorithmus;

oder für alle Klassen in einem Paket:

import ch.studiprojekt.*;

Verwendet man die Klasse nun im Programm, weiss die Java Virtual Machine (JVM), wo sie diese Klasse bzw. die kompilierte Klasse (die .class Datei) suchen muss.

SuperAlgorithmus besterVariablenNameEver = new SuperAlgorithmus();

Es wäre nun nicht sehr praktisch für die JVM, wenn der gesamte Computer nach der Klasse durchsucht werden muss. Daher gibt man an, an welchen Orten sie suchen muss. Dazu gibt man dem Java Klassenpfad / Classpath eine Liste von Ordnern und .jar Dateien an.

Es braucht nur den obersten Ordner

Will man jetzt die Klasse „ch.studiprojekt.SuperAlgorithmus“ der JVM angeben, wäre es mühsam, wenn man das für jede Klasse machen muss. Daher gibt man einfach den Oberordner an, wo die JVM alle Klassen finden kann.

Obwohl die .class Datei im Ordner „Klassen/ch/studiprojekt/SuperAlgorithmus“ liegt, muss man im im Klassenpfad nur den Ordner „Klassen“ hinzufügen.

Hat man eine Applikation als .jar Datei gebündelt, stellt man diese in den lib Ordner des Projekts. Im Klassenpfad fügt man nun die Datei „libs/MeineApp.jar“ hinzu. So weiss die JVM, dass diese .jar Datei existiert und man dort nach Code nachschauen kann.

Der Klassenpfad beinhaltet also .jar Dateien plus Pfade zu 
den obersten Stufen der Ordnerhierarchie.

Anpassen des Klassenpfads in Windows und Unix

Um in Windows den Klassenpfad zu ändern, geht man auf Systemsteuerung -> Benutzerkonten -> Eigene Umgebungsvariablen ändern.

In Unix macht man folgendes:

export CLASSPATH=/home/myaccount/myproject/lib/MeineApp.jar:
/home/myaccount/myproject/klassen/

Denken Sie aber daran, dass diese Einstellungen global sind, was nicht immer Sinn macht. Oftmals macht es darum mehr Sinn, wenn man den Build Pfad des Projekts anpasst, um Libraries und Ordner hinzuzufügen (direkt in Eclipse oder IntelliJ).

Was ist statistische Standardisierung?

17.02.2017

Stellen Sie sich vor, Sie haben eine Menge statistische Daten und stellen diese grafisch dar. Es gibt jeweils beidesmal einen hübschen Hügel, welcher wie die Gauss’sche Glockenkurve aussieht. Sie möchten nun die beiden Hügel miteinander vergleichen – Dies geht aber nicht, den beide Hügel haben eine ganz andere Lage. Der eine ist irgendwo um die 0 und der andere liegt irgendwo bei 200.

Eine Standardisierung der beiden Daten kann Ihnen hierbei behilflich sein.

PS: Die Gauss’sche Glockenkurve heisst übrigens auch Normalverteilung und dieses Verfahren findet man auch unter dem Namen z-Transformation.

Wie sehen die Hügel nach der Standardisierung aus?

Wenn die Daten standardisiert wurden, liegt ihr Erwartungswert bei 0 und die Standardabweichung bei 1.

standardisierung

Quelle dieses genialen Bildes: http://www.statistics4u.info/fundstat_germ/ee_ztransform.html

Dabei gelten folgende Regeln:

  • Geht man vom Erwartungswert nach links und rechts „eine“ Standardabweichung findet man ca. 70% der Werte
  • Geht man vom Erwartungswert nach links und rechts „zwei“ Standardabweichungen findet man ca. 95% der Werte
  • Geht man vom Erwartungswert nach links und rechts „drei“ Standardabweichungen findet man ca. 99% der Werte

Und wie mache ich diese Standardisierung?

Die Formel, um Ihre Daten zu standardisieren, ist ganz simpel:

standardisierung2

In Python kann man dies mit Numpy Methoden folgendermassen erreichen:

X = (X - X.mean()) / X.std()

Mü oder X.mean() steht dabei für den Erwartungswert und sigma oder X.std() für die Standardabweichung.

Was ist der Erwartungswert?

Erwartungswert ist einfach gesagt einfach der Durchschnitt der Werte. Andere Namen dafür sind Mittelwert oder arithmetisches Mittel.

mittelwert

Was ist die Standardabweichung?

Die Standardabweichung ist der Wert, den die meisten Daten im Durchschnitt vom Erwartungswert abweichen. Es ist ein Mass für die Streubreite der Daten.

standardabweichung

Warum funktioniert das?

Nun, die Schritte, die in der Formel gemacht werden, kann man sich so vorstellen.

1. Zuerst rechnet man jeden Wert der Daten minus den Mittelwert. Der Mittelwert selber geht also nach 0, alle kleineren Werte sind dann links und alle grösseren Werte rechts davon. Der Hügel wird also quasi um den Mittelwert nach links verschoben, damit er genau über der 0 steht.

2. Dann steht der Hügel zwar am richtigen Ort, ist aber noch zu breit. Darum quetscht man den Hügel um den Faktor der Standardabweichung. An der Formel sieht man, dass das ganze nur in X-Richtung passiert, der Hügel ist also noch gleich gross wie vorher.