0

所以事情是这样的:我有一个类可以扫描点定义的包名称(例如com.this.package)以查找类,然后将它们添加到列表中。奇怪的是,当我在 IDE 中工作时它工作正常,但是当我将项目导出到可执行 jar 文件时,以及它所有需要的依赖项,它无法找到任何类。

代码如下所示:

private void discoverTestCases(String packageName) throws ClassNotFoundException, IOException {
System.out.println("2");
    ClassLoader classLoader = Thread.currentThread()
            .getContextClassLoader();
    System.out.println("3");
    String path = packageName.replace('.', '/');
    System.out.println("4"+ path);
    Enumeration<URL> resources = classLoader.getResources(path);

    System.out.println("5");
    List<File> dirs = new ArrayList<File>();

    while (resources.hasMoreElements()) {
        URL  resource = resources.nextElement();
        System.out.println(resource.getFile());
        System.out.println(resource.getPath());
        dirs.add(new File(resource.getFile()));
    }

    List<Class> classes = new ArrayList<Class>();

    for (File directory : dirs) {
        classes.addAll(findClasses(directory, packageName));
    }

getTestableClasses(classes);

}

如您所见,我添加了一些打印输出,以查看在运行时可以从哪里获得,但最后显示的是“5”。

你能帮我个忙吗?

谢谢!

4

1 回答 1

0

好吧,问题是,通过这种方式,ClassLoader 会尝试从它们的绝对路径加载类,这会导致它们所在的项目文件夹。但是当项目被打包在单个 JAR 文件中时,这个文件夹就不再存在了。所以解决方案是在 JAR 文件中搜索并使用 UrlClassLoader 加载它们:

File f = new File("file.jar");
    List<Class> classes = new ArrayList<Class>();

    URL [] urls = {new URL("jar:"+f.toURL()+"!/")};

    URLClassLoader classLoader = URLClassLoader.newInstance(urls);

    JarFile jarFile = new JarFile(f);
    Enumeration<JarEntry> e = jarFile.entries();
    String className=null;
    while(e.hasMoreElements()){
        JarEntry je = e.nextElement();

         if(je.isDirectory() || !je.getName().endsWith(".class")){
             continue;
         }

         className  = je.getName().substring(0,je.getName().length()-6);
         className = className.replace('/', '.');

         if(className.contains("test.smoke") || className.contains("test.ml") || className.contains("test.sanity")){
             System.out.println("classname::: "+className);
             Class c = Class.forName(className);
             classes.add(c);
         }
于 2013-02-05T10:02:42.947 回答