只需用他的名字在jar中加载一个类

时间:2014-11-15 18:39:21

标签: java class jar

我试图在jar中加载一个类,但没有成功。

URL url = null;
    try {
        url = new URL("jar:file:"+System.getProperty("user.dir")+File.separator+"games"+File.separator+gameName+"!/");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    URL[] urls = {url};
    URLClassLoader cl = URLClassLoader.newInstance(urls);
    try {
        String gameClassPath = null;
        JarFile jar = new JarFile(url.getPath().replace("file:", "").replace("!", ".jar"));
        Enumeration<JarEntry> entries = jar.entries();
        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();
            if (entry.getName().contains(gameName)) {
                gameClassPath = entry.getName().replace('/', '.').replace(".class", "");
            }
        }
        this.gameClass = cl.loadClass(gameClassPath);
        jar.close();
    } catch (ClassNotFoundException | IOException e) {
        e.printStackTrace();
    }

我认为问题来自可能不在正确位置的URLClassLoader

使用OP的更新编辑问题[在答案部分发布]

@spiderman版本仍然有错误。 我确定gameClass类型是Class<?>,而不是Class,但我不知道区别。

enter image description here

String pathToJar = System.getProperty("user.dir")+File.separator+"games"+File.separator+gameName;
    String requiredClassName = gameName;
    JarFile jarFile = new JarFile(pathToJar+".jar");
    Enumeration<JarEntry> e = jarFile.entries();

    URL[] urls = {new URL("jar:file:"+pathToJar+"!/")};
    URLClassLoader cl = URLClassLoader.newInstance(urls);

        while (e.hasMoreElements()) {
            JarEntry je = (JarEntry) e.nextElement();
            if(je.isDirectory() || !je.getName().endsWith(".class")){
                continue;
            }
            if (je.getName().contains(requiredClassName)){
                System.out.println(requiredClassName + " is found!"); 
            }
        String className = je.getName().substring(0,je.getName().length()-6);
        className = className.replace('/', '.');
        gameClass = cl.loadClass(className);
    }
    jarFile.close();

2 个答案:

答案 0 :(得分:1)

这就是我尝试过的,我可以让它发挥作用 但建议您参考“javassist”#39; jar使用ClassPool代替ClassLoader

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;


public class LoadTheClassFromJar {
public static void main(String[] args) throws IOException, ClassNotFoundException {
    String pathToJar = "E:\\myjarfolder\\MyProject.jar";
    String requiredClassName = "Hungry";
    JarFile jarFile = new JarFile(pathToJar);
    Enumeration<JarEntry> e = jarFile.entries();

    URL[] urls = { new URL("jar:file:" + pathToJar+"!/") };
    URLClassLoader cl = URLClassLoader.newInstance(urls);

        while (e.hasMoreElements()) {
            JarEntry je = (JarEntry) e.nextElement();
            if(je.isDirectory() || !je.getName().endsWith(".class")){
                continue;
            }
            if (je.getName().contains(requiredClassName)){
                System.out.println(requiredClassName + " is found!"); 
            }
        // -6 because of .class
        String className = je.getName().substring(0,je.getName().length()-6);
        className = className.replace('/', '.');
        Class c = cl.loadClass(className);
        System.out.println(c.getName());
    }   
}
}

<强>输出:

com.prash.MyClass
Hungry is found!
com.prash.Hungry

注意:我创建了自己的jar文件并转储到该目录以测试程序。我在该项目/ jar文件中有Hungry.javaMyClass.java

答案 1 :(得分:0)

问题解决了,但我真的不知道为什么...... 我使用File和toURI()。toURL()来获取url

File jarFile = new File(System.getProperty("user.dir")+File.separator+"games"+File.separator+gameName+".jar");

    URLClassLoader cl = new URLClassLoader( new URL[]{jarFile.toURI().toURL()} );

    JarFile jar = new JarFile(jarFile.toString());
    Enumeration<JarEntry> e = jar.entries();
    while (e.hasMoreElements()) {
        JarEntry je = (JarEntry) e.nextElement();
        if(je.isDirectory() || !je.getName().endsWith(".class")){
            continue;
        }
        if (je.getName().contains(gameName)){
            String className = je.getName().substring(0,je.getName().length()-6);
            className = className.replace('/', '.');
            gameClass = cl.loadClass(className);
            System.out.println(gameName + " is loaded!");
        }
    }
    jar.close();
    cl.close();