2014-11-22 53 views
2

// // UPDATE的Java如何从另一个罐子类加载到我的罐子以及如何使用它

现在我可以加载罐,但我怎么可以运行它的方法呢?

+0

你必须实现一个自定义类加载器 – 2014-11-22 14:03:45

+0

,我该怎么做?你可以请示例代码 – sentostv 2014-11-22 15:20:39

+0

我认为搜索* java创建自定义类加载器*并不困难。无论如何:http://publib.boulder.ibm.com/infocenter/javasdk/v1r4m2/index.jsp?topic=%2Fcom.ibm.java.doc.diagnostics.142%2Fhtml%2Fid1100。html – 2014-11-22 15:24:11

回答

0
  1. 用jar的文件url创建一个类加载器。
  2. 请教类加载器的名字
  3. 加载游戏的主类,创建游戏的主类
  4. 投它的一个新的实例来一些“游戏”界面插件加载器知道
  5. 调用接口的方法开始游戏。
+1

你能举个例子吗? – sentostv 2014-11-22 14:24:48

0

从那里你需要插入games.jar主要JAR文件:

  • 首先让网址为您games.jar文件(使用File.toURI().toURL()),并把它放在一个数组(我们称之为数组urlArray)。
  • 下获得URLClassLoader实例加载games.jar

    URLClassLoader urlClassLoader = URLClassLoader.newInstance(urlArray); 
    
  • 现在你可以实例从games.jar任何类与Class.forName如果你通过你刚刚创建的第三个参数的新的类装载器:

    Class<? extends Main> mainClass = (Class<? extends Main>) 
    Class.forName("Main", true, urlClassLoader); 
    
  • mainClass您现在可以调用您的方法:mainClass.loaded();

+0

然后我该如何运行这些类的代码? – sentostv 2014-11-22 15:49:33

+0

Class.forName()返回一个Class对象。调用此对象的newInstance()以获取您的类的实例,然后您可以调用它的任何方法。 – 2014-11-23 15:09:33

+0

好的,你能帮助我吗?我有一个装有装载器的罐子,在第二个罐子里有一个我想从第一个罐子运行的方法,我必须做什么? – sentostv 2014-11-26 15:23:02

1

这有两个部分。首先,你需要导入jar。这可以在运行时使用轻微hack with reflection来完成:

import java.io.File; 
import java.lang.reflect.Method; 
import java.net.URL; 
import java.net.URLClassLoader; 
public void importJar(File file) { 
    Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); 
    addURL.setAccessible(True); 
    addURL.invoke(URLClassLoader.getSystemClassLoader(), new Object[] {file.toURI().toURL()}); 
}  

现在,你可以在运行时导入一个罐子。如果你只是有路径罐子,你可以很容易地将其转换为File

importJar(new File("path/to/jar")); 

其次,你需要找到你的罐子中定义的类。似乎没有内置的方法来执行此操作,因此您必须手动检查jar本身的类。

import java.lang.Class; 
import java.util.ArrayList; 
import java.util.Enumeration; 
import java.util.jar.JarFile; 
import java.util.jar.JarEntry; 
public List<Class<?>> findJarClasses(File file) { 
    ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); 
    JarFile jar = new JarFile(file); 
    Enumeration<JarEntry> entries = jar.entries(); 
    while (entries.hasMoreElements()) { 
     JarEntry entry = entries.nextElement(); 
     String name = entry.getName(); 
     if (name.endsWith(".class")) { 
      name = name.substring(0, name.lastIndexOf('.')); 
      Class<?> cls = Class.forName(name); 
      classes.add(cls); 
     } 
    } 
    return classes; 
} 

最后,你可以在类迭代,以确定其中是否实现所需的接口。

File jarFile = new File("path/to/Games.jar"); 
importJar(jarFile); 
List<Class<?>> classes = findJarClasses(jarFile); 
for (Class<?> cls : classes) { 
    if (cls.isInstance(YourInterface.class)) { 
     // Instantiate class. 
     YearInterface obj = (YourInterface)cls.newInstance(); 
     // Call `loaded()` method. 
     obj.loaded(); 
    } 
} 
+0

如何在这个类中运行一个方法? – sentostv 2014-11-22 17:33:10

+0

如果构造函数有参数,你可以使用'cls.newInstance()'或'cls.getConstructor(ArgumentClasses ...)。newInstance(arguments)''实例化类。另见我的更新。 – cpburnz 2014-11-22 17:55:34

+0

我总是得到一个错误[11:35:29错误]:启用Arcade v0.1时发生错误(是否是最新版本?) java.lang.NoClassDefFoundError:arcade/interfaces/game – sentostv 2014-11-23 10:36:02