2012-10-19 43 views
8

Tôi hiện đang tạo một hệ thống plugin (Lần thử đầu tiên), nhìn vào mã người khác Tôi đang cố gắng ghép các bộ nạp lớp của riêng mình và tải các plugin từ một thư mục. tập tin)Java - Tự động tải các lớp học

Vấn đề của tôi là bất cứ khi nào tôi cố gắng tải lớp đó bằng trình nạp lớp của tôi, mọi nhập trong plugin tham chiếu chương trình không được trình nạp lớp tìm thấy. (ví dụ: MyClass mở rộng Plugin, com.mgmc.plugins noclassdeffound) Không gian tên khác nhau?

Một số mẫu mã: 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; 
    } 
} 
} 

Plugin Tôi tải: (Chú thích không tìm thấy một trong hai)

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 { 
} 

Làm thế nào tôi gọi lớp được nạp :

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

Tôi thấy điều này là tầm thường đối với những người biết họ đang làm gì!

+2

bạn không phải là người chịu trách nhiệm. Những người trên SO đang đặt câu hỏi hoặc trả lời họ. Thật tuyệt. –

+0

Tôi ngạc nhiên: bạn không có gói nào? Tôi hy vọng classLoader.loadClass ("a.b.c.d.game", true); – Aubin

+0

Tôi đang cố gắng không thêm gói, Chỉ vì cách tôi muốn mọi người có thể thêm minigames của riêng mình - tôi biết nó đi ngược lại quy ước nhưng theo cách này tôi có thể có tất cả minigames trong một thư mục (Hoặc Jar) Cuối cùng nó sẽ quét thư mục cho tất cả các tệp, kiểm tra tệp .class và .jar và tải chúng (Không gói nào nghĩa là không có thư mục con quét) –

Trả lời

4

CUỐI CÙNG! Sau một ngày rưỡi tìm kiếm, Vulcan đã chỉ cho tôi đi đúng hướng: Tôi đã thay đổi GameClassLoader tới:

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

và cuối cùng thêm vào url cơ sở để các getResourceAsStream()

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

Cảm ơn rất nhiều cho những người giúp đỡ của bạn!

+3

Rất vui khi được giúp đỡ! Đừng quên để đánh dấu câu trả lời của riêng bạn như được chấp nhận cho các tài liệu tham khảo trong tương lai của người khác. – Vulcan

0

Cố gắng thêm slash dẫn vào con đường tài nguyên: final InputStream in = getResourceAsStream("/" + name.replace('.', '/') + ".class");

Đây là điều tôi phải cố gắng mỗi khi tôi kêu gọi getResourceAsStream(). Tôi vừa thử lại lần nữa. Đường dẫn ở đây liên quan đến gói của lớp được sử dụng để gọi getResourceAsStream(), do đó, dấu gạch chéo hàng đầu là cần thiết để nói "bắt đầu từ thư mục gốc".

+0

Thật không may điều này ngăn chặn nó tải ở tất cả, Vấn đề không tải lớp; nó tải phụ thuộc vào lớp: java.lang.NoClassDefFoundError: com/mcgm/game/Minigame Lớp học được tìm thấy hoàn toàn ổn. –

Các vấn đề liên quan