用资源导出瓶子 [英] Exporting jars with resources

查看:153
本文介绍了用资源导出瓶子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过构建许多小型,模块化的项目来构建一个大型的Java项目。我希望每个小项目都是完全独立的,拥有所有的资源(如图像)。



我正在使用Eclipse。如果配置构建路径以添加其中一个模块化项目,则资源引用不起作用。该系统找不到指定的文件。如果我导出一个jar并将它包含在配置构建路径的库选项卡中,同样的事情发生。



我做了一些实验,找出一种方法让它上班。我已经尝试使用源文件夹的资源,并使用:

  //如果资源位于包文件中, 
//不在我想要的地方
getClass()。getResourceAsStream(resource.abc)

  new FileInputStream(path / to / resource.abc)

也许我错过了项目结构的一些内容。我一直能够从IDE中的单个项目中获取资源,而无需任何麻烦。当您开始链接多个项目或将其包含为jar时,有什么不同?



我的理想结构是将另一个文件夹与src文件夹位于同一级别我的项目的根,这将包含我的所有资源,独立于源代码。

解决方案

这个解决方案适用于我: / p>

  / ** 
*
* @author David
* /
public class JavaApplication60 {
/ **
* @param args命令行参数
* /
public static void main(String [] args){
// http ://img.viralpatel.net/java-cup-logo.png

//位于不在当前一个包中的包
URL url = new JavaApplication60()。getResource( /javaapplication60/newpackage/java-cup-logo.png);
System.out.println(url.getPath());
//位于同一个包
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); //系统类。
}
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); //系统类。
}
return cl.getResource(name);
}


/ *
*如果名称不是
* absolute,则resolveName方法会添加包名前缀,并删除任何前导的/ 如果这个名字是绝对的它是
*可能,虽然不常见的是,在差异包中共享
*相同的资源的类。
* /
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);
}
返回名称;
}
}

我的包结构如下所示:





参考资料




I'm trying to build a large Java project by building many small, modular projects. I want each small project to be entirely self contained, holding all of its resources (such as images).

I am using Eclipse. If I configure the build path to add one of the modular projects, the resource references don't work. The system cannot find the file specified. The same thing occurs if I export a jar and include that in the libraries tab of configure build path.

I've done some experimenting, and haven't been able to figure out a way to get it to work. I've tried using source folders for resources and using:

// this works if resource is located in package alongside class file, 
// not where I want it
getClass().getResourceAsStream("resource.abc")

or

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

Maybe I'm missing something about how projects are structured. I've always been able to get resources to work from a single project within the IDE without any trouble. What is different when you start linking multiple projects or including them as jars?

My ideal structure would be to have another folder, at the same level as the src folder in the root of my project, that would contain all of my resources, separate from source code. This is how it was set up before all the trouble trying to link projects/jars.

解决方案

This solution worked for me:

/**
 *
 * @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 looked like this:

References:

这篇关于用资源导出瓶子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆