2010-03-10 15 views
11

Bir Tomcat 5.5 sunucusunda, sistem sınıf yoluna bir sınıf koyarım (ve catalina.bat dosyasını seçmek için değiştirin) veya sınıfı paylaşılan lib dizinine koyarsam. Artık, WEB-INF lib/class dizinlerinde sınıfları olmayan aynı sınıfı kullanan iki farklı uygulamam varsa, sınıfın aynı örneğini kullanırlar. Bir sınıf yükleyicinin, bulamıyorsa bir sınıf bulması için ana sınıf yükleyiciye devredeceği konsepti anlıyorum, bu nedenle, sınıf WEB-INF/sınıflarında veya WEB-INF/lib'de bulunmadığından WebAppX sınıf yükleyicisi, sırasıyla ortak, ortak ve sistem sınıf yükleyicisini deneyecek.Tomcat üzerinde birden çok uygulamayla sınıf yükleyicisi davranışı

Bununla birlikte, bu yöntem iki farklı uygulamanın bu yöntemi kullanarak bir bağlamı paylaşabilmesinin garip görünmesine neden oluyor. Birisi bunun neden böyle olduğunu anlamama yardımcı olabilir. Örneğin. Aşağıdaki kodda, iki servletin her biri ayrı savaşlarda dağıtılırken, CommonCounter paylaşılır ve diğeri tarafından artırılan sayaç değerlerini okuyabilirler.

iki ayrı uygulamalar bu şekilde bir bağlam paylaşabilirsiniz bana karşı sezgisel görünen Düzen. Aslında, sınıfın aynı örneğine sahiplerse, iki farklı uygulamada çoklu okuma/senkronizasyon uygulayabilirler, ki bu son derece mantıksız görünüyor. Eğer gözlemlemek davranışı gözlemlemek neden

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"); 
    } 
} 
+1

Soruyu anlamıyorum: Tomcat'in sistem sınıf yükleyicisindeki sınıfların tüm uygulamalar arasında paylaşıldığını kendiniz açıklıyorsunuz. Bu nedenle, her iki uygulama da aynı sınıfa erişir ve böylece aynı statik alanlardan okunur ve birbirlerinin etkisini görebilirler. –

+0

Evet, ancak iki ayrı uygulamanın bu bağlamda bir içeriği paylaşabildiğini bana karşı sezgisel karşımıza çıkıyor. Aslında, sınıfın aynı örneğine sahiplerse, iki farklı uygulamada çoklu okuma/senkronizasyon uygulayabilirler, ki bu son derece mantıksız görünüyor. – saugata

cevap

10

comments söylediği gibi, doğru açıkladım.

Anahtar, ClassLoader öğelerinin nasıl yapılandırıldığıdır. Bir JVM içindeki iki ClassLoader'ın her biri bir sınıfı yükleyebilmesi ve dolayısıyla statik alanların ayrı, bağımsız kopyalarını içermesi tamamen mümkündür. "statik" bir JVM'ye değil, bir ClassLoader'a 'global' bir şey yapar. Tomcat, sanırım, paylaşılan kütüphanelerle konteynır düzeyinde bir ClassLoader taşıyamadı ve her nasılsa her uygulama ClassLoader'ı paylaşımlı kütüphaneleri ayrı ayrı yüklemeye zorladı.

Ancak bu, J2EE API'leri ve uygulaması gibi diğer yaygın sınıflar için biraz savurganlık olur. Ve prensip olarak, sınıflar yine de bu ClassLoader yapısına bağlı olmamalıdır.

Bu nedenle, uygulama bağımlılıkları Tomcat'in paylaşılan kitaplık klasörlerine koymamalısınız. Bu 'çözüm'. Uygulamanızı, J2EE web uygulamaları ilkesine aykırı olan, konteynerin özel kurulum ve dağıtımına bağlar. Her uygulama için WEB-INF/lib'e bağımlılık kopyaları koyun.

Gözlemlediğiniz davranış, bunu yapmanın başka bir nedenidir: uygulamalar birbirinden daha az yalıtılmış hale gelir. Bu, karşı-sezgisel bir davranış olarak bana çarpmaz, ama sanırım Tomcat'in bu şeyler hakkında nasıl çalıştığı ve düşündüğü için kullanıyorum.

+0

İki webapps arasında nesneleri paylaşmam gereken bir benzer sorun yaşıyorum. Öyle görünüyor ki, nesneyi sistem sınıf yükleyicisine koymak muhtemelen tek çözümdür. Http://stackoverflow.com/questions/9453109/using-jndi-to-share-servlet-session-objects-and-data-in-tomcat – ziggy

+1

Belki de ... webapps üzerinden paylaşmak kesinlikle bir şey değil Böyle yapmak için amaçlanmıştır. (Bununla birlikte .ear dosyalarına bakın) Yukarıdaki sebeplerden dolayı işe yarayabilir, ancak çalışması garanti edilemez. –

İlgili konular