导出带有资源的JAR包

3
我正在尝试通过构建许多小型,模块化项目来构建一个大型Java项目。我希望每个小项目都是完全自包含的,持有其所有资源(如图像)。
我使用的是Eclipse。如果我配置构建路径以添加其中一个模块化项目,则资源引用将无法正常工作。系统找不到指定的文件。如果我导出一个jar并在“配置构建路径”的库选项卡中包含它,则会发生相同的事情。
我进行过一些实验,但无法想出解决办法。我尝试使用源文件夹来存放资源,并使用:
// this works if resource is located in package alongside class file, 
// not where I want it
getClass().getResourceAsStream("resource.abc")

或者
new FileInputStream("path/to/resource.abc")

也许我对项目结构还有所不了解。在IDE中,我总是能够轻松地从单个项目中获取资源而没有任何问题。当您开始链接多个项目或将它们作为jar包包含时有什么不同之处?

我的理想结构是,在项目根目录的src文件夹同级别处,再建立一个文件夹来容纳所有资源,与源代码分开。这就是在尝试链接项目/ jar包时遇到麻烦之前的设置。


尝试将它们放置在src文件夹中,至少对我来说是有效的。虽然我将它们放置在src/META-INF/... - Sebastian Hoffmann
1
你是否考虑过使用构建系统,例如Maven?它可以帮助你组织一个模块化的项目(包括资源),并配置Eclipse将这些模块导入为项目。除此之外,还有无数其他好处,不妨一试! - Duncan Jones
3个回答

1
这个解决方案对我有效:
/**
 *
 * @author David
 */
public class JavaApplication60 {
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    //http://img.viralpatel.net/java-cup-logo.png

    //located in a package not in the current one
    URL url = new JavaApplication60().getResource("/javaapplication60/newpackage/java-cup-logo.png");
    System.out.println(url.getPath());
    //located in same package
    url = new JavaApplication60().getResource("/javaapplication60/java-cup-logo.png");
    System.out.println(url.getPath());
}

public InputStream getResourceAsStream(String name) {
    name = resolveName(name, this.getClass());
    ClassLoader cl = getClass().getClassLoader();
    if (cl == null) {
        return ClassLoader.getSystemResourceAsStream(name); // A system class.
    }
    return cl.getResourceAsStream(name);
}

public java.net.URL getResource(String name) {
    name = resolveName(name, this.getClass());
    ClassLoader cl = getClass().getClassLoader();
    if (cl == null) {
        return ClassLoader.getSystemResource(name);  // A system class.
    }
    return cl.getResource(name);
}


/*
 * The resolveName method adds a package name prefix if the name is not
 * absolute, and removes any leading "/" if the name is absolute. It is
 * possible, though uncommon, to have classes in diffent packages sharing
 * the same resource.
 */
private String resolveName(String name, Object clazz) {
    if (name == null) {
        return name;
    }
    if (!name.startsWith("/")) {
        Class c = clazz.getClass();
        while (c.isArray()) {
            c = c.getComponentType();
        }
        String baseName = c.getName();
        int index = baseName.lastIndexOf('.');
        if (index != -1) {
            name = baseName.substring(0, index).replace('.', '/') + "/" + name;
        }
    } else {
        name = name.substring(1);
    }
    return name;
}
}

我的包结构看起来像这样:

My package structure for above code

参考资料:


0

要为您的资源添加另一个源文件夹,首先创建该文件夹。在Java透视图中,选择项目,然后从上下文菜单中选择“配置构建路径”。在源文件夹选项卡中,您可以将新创建的文件夹设置为项目的源文件夹。从那时起,该文件夹下的所有资源都可以与项目类一起导出到JAR文件中。

顺便说一下,您为getResourceAsStream指定的路径只是资源文件名(如果资源与类位于同一包中)或者是相对路径名称(以斜杠开头),表示从您正在使用的源文件夹中获取资源。


0

您有多个项目组成一个单一的应用程序吗?如果您通过Eclipse运行它,一切都正常吗?
如果是的话,那么只需在您的主项目中执行 导出为可运行的Jar文件 即可。这也应该可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接