2010-11-04 16 views
25

Herkese merhaba ve ilginiz için teşekkürler! Hem kolay hem de açık olması gereken bir sorunum var, ama ben sıkışıp kaldım.Özel ClassLoader nasıl kullanılır?

Özel bir ClassLoader aracılığıyla bir 3. taraf kitaplığı tarafından kullanılmak üzere dinamik olarak oluşturulmuş Java sınıfları sunmak istiyorum.

Artık benim sorunum: Doğrudan bunları kendim yüklemediğimde bu sınıfları yüklemek için özel ClassLoader'ımı nasıl ayarlayabilirim?

Belirli bir sınıfı yüklemek için ClassLoader'ımı kullandığımda, bu sınıfın ClassLoader'ı oldu ve bu sınıftan yüklenen tüm sınıfların ClassLoader'ım aracılığıyla kanalize edileceğini düşündüm.

Bu resmi eğiticiyi izleyerek özel bir ClassLoader oluşturdum: http://java.sun.com/developer/onlineTraining/Security/Fundamentals/magercises/ClassLoader/help.html.

public class DynamicClassloader extends ClassLoader { 

    private Map<String, Class<?>> classesMap = new HashMap<String, Class<?>>(); 

    public DynamicClassloader(ClassLoader parent) { 
     // Also tried super(parent); 
     super(sun.misc.Launcher.getLauncher().getClassLoader()); 
    } 

    // Adding dynamically created classes 
    public void defineClass(String name, Class<?> clazz) { 
     classesMap.put(name, clazz); 
    } 

    @Override 
    protected Class<?> findClass(String name) throws ClassNotFoundException { 
     // load from parent 
     Class<?> result = findLoadedClass(name); 
     if (result != null) { 
      return result; 
     } 
     try { 
      result = findSystemClass(name); 
     } catch (Exception e) { 
      // Ignore these 
     } 
     if (result != null) { 
      return result; 
     } 
     result = classesMap.get(name); 
     if (result == null) { 
      throw new ClassNotFoundException(name); 
     } 
     return result; 
    } 
} 

böyle kodda başka Bunu biryere kullanmak istedi:

Şimdi
ClassLoader thisClassLoader = this.getClass().getClassLoader(); 
((DynamicClassloader) thisClassLoader).defineClass(className, dynClass); 

benim sorunum (ben 3. parti kütüphane sınıfının findSystemClass(name) çağırdığınızda, ebeveyn ClassLoader bu sınıfı bulur olmasıdır çünkü sınıf yolundadır ve ClassLoader'ı olur. Ve ana ClassLoader özel ClassLoader'ımı bilmediğinden, etkin bir şekilde kullanımdan kaldırıldı ve this.getClass().getClassLoader(), DynamicClassLoader'a dökülemiyor. Başka bir yaklaşım, ClassLoader'ımın -Djava.system.class.loader=my.DynamicClassloader JVM argümanı üzerinden sistem ClassLoader olmasını sağlamaktır.

... 
at de.unisaarland.cs.st.DynamicClassloader.findClass(DynamicClassloader.java:39) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:307) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:248) 
at java.lang.ClassLoader.findSystemClass(ClassLoader.java:916) 
at de.unisaarland.cs.st.DynamicClassloader.findClass(DynamicClassloader.java:39) 
    ... 

Bu yapmak gerçekten kolay olmalı, ama ben fikir gelmiyordu şimdi olduğum ... herhangi bir yardım büyük takdir: Ama bu bana bir StackOverflowError veriyor!

+0

İlgili http://stackoverflow.com için/questions/6366288/nasıl yapılır-varsayılan-sınıf-loader-in-java, http://stackoverflow.com/questions/5380275/replacement-system-classloader-for-classes-in-jars-containing-jars/19128964 # 191 28964 ve http: // stackoverflow.com/sorular/5380275/değiştirme sistemi tarafından classloader-sınıflar-in-kavanoz içeren-kavanozlar için. – roesslerj

cevap

19

Soruyu anladığımdan emin değilim, bir 3. parti kitaplığınız var ve sınıf yükleyicinizi sınıfları yüklemek için kullanmasını istiyorsunuz. Eğer şanslıysanız

üçüncü şahıs lib size Thread.currentThread().getContextClassLoader() ile bu classloader erişebilir aynı iş parçacığı Eğer Thread.currentThread().setContextClassLoader(myClassLoader) kullanılarak ayarlanan olabilir ipler bağlam classloader ...

başka nokta ise, ama kesin değil kullanır

: En bağlamda önemlidir, ayrıca onun ebeveyne delege (yerine ilk temsilci çalışırken)

yorumunuzun ardından Düzenlendi önce sınıf yüklemeye çalışır bir ebeveyn-son classloader yazabilmesidir

parent_last classloader kütüphaneniz thread context classloader'a güvenmiyorsa bir fark yaratacaktır, daha sonra üst-son classloader ile kütüphaneyi yüklemeniz gerekir, böylece sınıf yükleyicinizi ana yükleyici yerine kütüphane için classloader olarak ayarlarsınız. Ayrıca ebeveyn-ilk davranışıyla ancak 3. parti kütüphane için bir classloader yapabilir

sizin classloader) ana ... ...

And a good link about classloaders...

+0

ContextClassLoader iyi bir fikir, bunu deneyecek. Çok teşekkürler! Ebeveyn-son sınıf yükleyicisine gelince: Bunun bir fark yaratacağını düşünmüyorum. Yüklediğim sınıfı tanımlamak istemiyorum, sadece ClassLoader'ımın geçerli ClassLoader olmasını istiyorum, böylece 'findClass' için sonraki tüm çağrılar kanal üzerinden iletilir ... – roesslerj

+0

Ebeveyn-son sınıf nasıl yazılır yükleyici? Mevcut bir uygulama yok mu? değilse, o zaman bu bir commom problemi değildir ya da çözmek için başka bir, daha iyi bir yol vardır. –

+0

Bağlantı bozuk – grimmeld

İlgili konular