2012-10-19 23 views
8

Şu anda bir eklenti sistemi (İlk denemem) yaratıyorum, diğer insanlara bakıyorum kodları kendi classloader'ımı bir araya getirmeye çalışıyorum ve bir dizinden yüklenen eklentileri aldım. files)Java - Dinamik olarak yükleme sınıfları

Sorunum, sınıfı yükleyiciyle birlikte yüklemeyi denediğimde, programa başvuran eklenti içindeki herhangi bir içeriğin sınıf yükleyicisi tarafından bulunmadığıdır. (yani: MyClass Eklentiyi genişletir, com.mgmc.plugins noclassdeffound) Farklı ad alanı?

Bazı örnek kod: ClassLoader:

/* 


* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package com.mcgm.game.provider; 

import com.mcgm.utils.Misc; 
import com.mcgm.utils.Paths; 
import java.awt.AWTPermission; 
import java.io.*; 
import java.net.MalformedURLException; 
import java.net.SocketPermission; 
import java.net.URL; 
import java.security.CodeSigner; 
import java.security.CodeSource; 
import java.security.Permissions; 
import java.security.ProtectionDomain; 
import java.util.PropertyPermission; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

/** 
* 
* @author Tom 
*/ 
public class GameClassLoader extends ClassLoader { 
private final ProtectionDomain domain; 
private final URL base; 

public GameClassLoader(final URL url) { 
    base = url; 
    final CodeSource codeSource = new CodeSource(base, (CodeSigner[]) null); 
    domain = new ProtectionDomain(codeSource, getPermissions()); 
} 

public void loadGames() { 
    for (File f : Paths.compiledFolder.listFiles()) { 
     try { 
      Class c = loadClass(f.getPath()); 
      Misc.outPrint(c.getName()); 
     } catch (ClassNotFoundException ex) { 
      Logger.getLogger(GameClassLoader.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

private Permissions getPermissions() { 
    final Permissions ps = new Permissions(); 
    ps.add(new AWTPermission("accessEventQueue")); 
    ps.add(new PropertyPermission("user.home", "read")); 
    ps.add(new PropertyPermission("java.vendor", "read")); 
    ps.add(new PropertyPermission("java.version", "read")); 
    ps.add(new PropertyPermission("os.name", "read")); 
    ps.add(new PropertyPermission("os.arch", "read")); 
    ps.add(new PropertyPermission("os.version", "read")); 
    ps.add(new SocketPermission("*", "resolve")); 
    ps.add(new FilePermission(Paths.compiledFolder.getPath(), "read,write,delete")); 
    ps.setReadOnly(); 
    return ps; 
} 

@Override 
@SuppressWarnings("rawtypes") 
public Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException { 
    Class clazz = findLoadedClass(name); 

    if (clazz == null) { 
     try { 
      byte[] bytes = loadClassData(name); 
      clazz = defineClass(name, bytes, 0, bytes.length, domain); 
      if (resolve) { 
       resolveClass(clazz); 
      } 
     } catch (final Exception e) { 
      clazz = super.loadClass(name, resolve); 
     } 
    } 

    return clazz; 
} 

public byte[] loadClassData(final String name) { 
    try { 
     final InputStream in = getResourceAsStream(name.replace('.', '/') + ".class"); 
     final byte[] buffer = new byte[4096]; 
     final ByteArrayOutputStream out = new ByteArrayOutputStream(); 
     int n; 
     while ((n = in.read(buffer, 0, 4096)) != -1) { 
      out.write(buffer, 0, n); 
     } 
     return out.toByteArray(); 
    } catch (IOException ex) { 
     Logger.getLogger(GameClassLoader.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    return null; 

} 

@Override 
public URL getResource(final String name) { 
    try { 
     return new URL(base, name); 
    } catch (final MalformedURLException e) { 
     return null; 
    } 
} 

@Override 
public InputStream getResourceAsStream(final String name) { 
    try { 
     return new URL(base, name).openStream(); 
    } catch (final IOException e) { 
     return null; 
    } 
} 
} 

Ben yükleme am Eklenti:

import com.mcgm.GameInfo; 
import com.mcgm.game.Minigame; 
    @GameInfo(name = "RandomGame", 
description = "A really long and boring game.", 
authors = {"Tom", "Is", "The", "Greatest"}, 
version = 0.1, 
maxPlayers = 100, 
teamBased = false, 
teamAmount = -1, 
PvP = false) 
public class game extends Minigame { 
} 

Nasıl yüklü olması sınıfını çağırıyorum (ek açıklama ya bulunmazsa) :

GameClassLoader classLoader = new GameClassLoader(Paths.compiledFolder.toURI().toURL()); 
      classLoader.loadClass("game", true); 

Bu ne yaptığını bilenler için önemsiz olduğunu düşünüyorum!

+2

Bir yük adamı değilsiniz. SO üzerindeki insanlar ya sorular soruyor ya da cevap veriyorlar. Çok havalı. –

+0

Şaşırdım: Hiç paketiniz yok mu? ClassLoader.loadClass ("a.b.c.d.game", true) beklerim; – Aubin

+0

Paketleri eklememeye çalışıyorum, Sadece insanların kendi minigameslerini ekleyebilmelerini istediğim için - bunun kurallara aykırı olduğunu biliyorum, ancak bu şekilde tüm mini oyunları tek bir klasörde bulabiliyorum (Veya Jar) Sonunda, tüm dosyalar için klasörü tarayacak, .class ve .jar dosyalarını kontrol edecek ve bunları yükleyecektir (Hiçbir paket, tarama alt dizinleri anlamına gelmez) –

cevap

4

FINALLY! Bir gün ve arama bir buçuk sonra, Vulcan bana doğru yönde işaret etti: Ben GameClassLoader değiştirdi:

public GameClassLoader(final URL url, ClassLoader parent) { 
    super(parent); 

ve nihayet getResourceAsStream()

final InputStream in = getResourceAsStream(base.getFile() + "/" + name.replace('.', '/') + ".class"); 

teşekkür taban url eklendi Yardımınız için çok teşekkürler!

+3

Yardım ettiğim için sevindim! Başkalarının gelecekteki referansları için kabul edilen kendi cevabınızı işaretlemeyi unutmayın. – Vulcan

0

kaynak yoluna giden çizgi eklemeniz deneyin: final InputStream in = getResourceAsStream("/" + name.replace('.', '/') + ".class");

Bu ben getResourceAsStream() arıyorum her zaman denemek zorunda şeydir. Bunu senin için tekrar denedim. Buradaki yol, getResourceAsStream() numaralı telefonu aramak için kullanılan sınıf paketine göredir, bu nedenle "kökten başla" demek için önde gelen eğik çizgi gereklidir.

+0

Ne yazık ki bu, yüklemeyi hiç durmadan durdurur, Sorun sınıfı yüklemiyor; sınıf bağımlılıkları yükleniyor: java.lang.NoClassDefFoundError: com/mcgm/oyun/Minigame Sınıf kesinlikle iyi bulundu. –

İlgili konular