Classloader Verhalten des Tomcat-mit mehreren Anwendungen
Auf einem Tomcat-server 5.5, ich habe eine Klasse in der system-classpath (und ändern catalina.bat, um ihn abzuholen), oder wenn ich die Klasse in der shared lib. Nun, wenn ich zwei verschiedene Programme mit der gleichen Klasse, die haben nicht die Klasse in Ihre WEB-INF lib/classes Verzeichnisse, die Sie verwenden, die gleiche Instanz der Klasse. Ich verstehe das Konzept, dass ein classloader delegieren, um es in den übergeordneten classloader für die Suche nach einer Klasse, wenn Sie es nicht finden können, also in diesem Fall, da die Klasse nicht vorhanden ist, in das WEB-INF/classes und WEB-INF/lib die WebAppX classloader versuchen die shared, common und system-classloader bzw.
Aber das wirkt irgendwie komisch auf mich, dass zwei verschiedene Anwendungen gemeinsam nutzen können Zusammenhang mit dieser Methode. Könnte jemand mir helfen zu verstehen, warum dies so ist. z.B. im folgenden code die beiden servlets sind jeweils eingesetzt in separaten kriegen, während CommonCounter freigegeben ist, und Sie können Lesen Sie die Werte der Zähler inkrementiert den anderen.
Bearbeiten
Es scheint counter-intuitive, um mir, dass Sie zwei separate Anwendungen teilen können, einen Kontext, in diesem Mode. In der Tat, wenn Sie die gleiche Instanz der Klasse, Sie können auch implementieren, die multithreading/- Synchronisation über zwei verschiedene Anwendungen, die erscheint äußerst kontraintuitiv.
package com.test;
public class CommonCounter {
public static int servlet1;
public static int servlet2;
}
public class Servlet1 extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
CommonCounter.servlet1++;
System.out.println("Other one had "+CommonCounter.servlet2+" hits");
}
}
public class Servlet2 extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
CommonCounter.servlet2++;
System.out.println("Other one had "+CommonCounter.servlet1+" hits");
}
}
- Ich verstehe nicht, die Frage: Sie erklären selbst, dass die Klassen in der system-classloader von Tomcat sind geteilt zwischen allen Anwendungen. Deshalb werden beide Programme greifen auf die gleiche Klasse und so Las aus dem gleichen statische Felder und sehen die Wirkung der jeweils anderen.
- Ja, aber es scheint counter-intuitive zu mir, dass Sie zwei separate Anwendungen teilen können, einen Kontext, in diesem Mode. In der Tat, wenn Sie die gleiche Instanz der Klasse, Sie können auch implementieren, die multithreading/ - Synchronisation über zwei verschiedene Anwendungen, die erscheint äußerst kontraintuitiv.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Als Kommentare sagen, das hast du richtig erklärt, warum Sie beobachtet das Verhalten, das Sie beobachtet.
Ist der Schlüssel, wie Classloadern strukturiert sind. Es ist durchaus möglich, für zwei Classloadern innerhalb einer JVM auf jeder laden einer Klasse und enthält daher eine getrennte, unabhängige Kopien der statischen Felder. "static" macht etwas 'global' zu einem ClassLoader, nicht eine JVM. Tomcat, ich nehme an, nicht halten konnte eine container-Ebene ClassLoader mit shared libraries und irgendwie die Kraft, jedes app-ClassLoader zum laden von shared libraries separat.
Aber das wäre ein bisschen verschwenderisch für andere gemeinsame Klassen wie J2EE-APIs und-Umsetzung. Und im Prinzip-Klassen sollten nicht davon abhängen, diese ClassLoader-Struktur sowieso.
Dies ist, warum Sie sollten nicht Abhängigkeiten der Anwendung im Tomcat - "shared libraries" - Ordner. Das ist die 'Lösung'. Es knüpft Ihre Anwendung auf die container-spezifischen setup und Bereitstellung, die gegen den Grundsatz von J2EE-web-apps. Nur Kopien von Dateien in WEB-INF/lib für jede Anwendung.
Das Verhalten, das Sie beobachten, ist ein weiterer Grund, dies nicht zu tun: apps werden weniger von einander isoliert. Es muss nicht Schlag mich als Kontra-intuitiv Verhalten, aber ich nehme an, einfach weil ich es gewohnt bin wie Tomcat arbeitet und denkt über diese Dinge.