简体   繁体   English

getResource()无法加载jar中的内容

[英]getResource() can't load content in a jar

I can successfully load resources that stand in some package of my src/ dir in eclipse. 我可以在eclipse中成功加载位于我的src / dir的某个包中的资源。 Now, I export the jar (right click src, export, jar, and keep default settings) and can't have the resource loaded in another eclipse project. 现在,我导出jar(右键单击src,export,jar,并保留默认设置),并且不能在另一个eclipse项目中加载资源。

I build the path to the resource by indicating a class standing in the same package name: 我通过指示站在相同包名中的类来构建资源的路径:

URL out = getClass().getClassLoader().getResource(packageName(getClass())+"file.glsl");
// out is null when loaded from a jar!!   

protected static String packageName(Class<?> clazz){
    return packageName(clazz.getPackage());
}
protected static String packageName(Package p){
    return c + p.getName().replace('.', c) + c;
}
protected static char c = File.separatorChar;

Do you see any wrong way? 你看错了吗? I tried: 我试过了:

  • getClass().getResource() 的getClass()。getResource()方法
  • getClass().getClassLoader().getResource() 的getClass()。getClassLoader()。getResource()方法
  • getClass().getClassLoader().getResourceAsStream() 的getClass()。getClassLoader()。的getResourceAsStream()
  • Thread.currentThread().getContextClassLoader().getResource() Thread.currentThread()。getContextClassLoader()。getResource()方法
  • adding/removing the '/' char at the begining of the package name 在包名称的开头添加/删除'/'字符
  • using either '/', '\\', or File.separatorChar, and even '.', all failed. 使用'/','\\'或File.separatorChar,甚至'。',都失败了。

I verified that: 我证实了这一点:

  • jar contains the resource (expanding the jar content in eclipse project's "Referenced Libraries") jar包含资源(在eclipse项目的“Referenced Libraries”中扩展jar内容)
  • packageName(getClass())+filename) returns a clean name: "\\org\\jzy3d\\plot3d\\rendering\\ddp\\algorithms\\dual_peeling_init_vertex.glsl" packageName(getClass())+ filename)返回一个干净的名称:“\\ org \\ jzy3d \\ plot3d \\ rendering \\ ddp \\ algorithms \\ dual_peeling_init_vertex.glsl”

I endlessly retrieve a null :/ 我无休止地检索一个null:/


EDIT: screenshot and code to show that "that should work" 编辑:截图和代码,以显示“应该工作”

在此输入图像描述

You can retrieve this a SSCCE zipped eclipse project here 你可以在这里检索这个SSCCE压缩的eclipse项目

A user class 用户类

public class User {
    public static void main(String[] args) {
        Loader pair = new Loader(SomeClass.class, "shade_vertex.glsl");
        System.out.println("found:" + pair.getURL());

    }
}

Providing class dynamically with new SomeClass().getClass() produce the same result. 使用新的SomeClass()动态提供类.getClass()产生相同的结果。

The loader 装载机

package com.pkg.loader;

import java.io.File;
import java.net.URL;

public class Loader {
    public Loader(Class<?> c, String file) {
        this(packageName(c.getPackage()), file);
    }

    public Loader(Package p, String file) {
        this(packageName(p), file);
    }

    protected Loader(String pack, String file) {
        this.pack = pack;
        this.file = file;
    }

    public String getStringPath() {
        return pack+file;
    }

    public URL getURL() {
        URL out = Thread.currentThread().getContextClassLoader().getResource(getStringPath());
        if(out==null)
            throw new RuntimeException("unable to find shader URL for :'"+getStringPath()+"'");
        return out;
    }

    protected static String packageName(Class<?> clazz){
        return packageName(clazz.getPackage());
    }

    protected static String packageName(Package p){
        return c + p.getName().replace('.', c) + c;
    }

    protected static char c = File.separatorChar;

    protected String pack;
    protected String file;
}

The marker class 标记类

public class SomeClass {}

First, try not to place source files directly in the default package (src). 首先,尽量不要将源文件直接放在默认包(src)中。 Create at least one package to wrap your source because when jars are exported, the src folder isn't included. 创建至少一个包来包装您的源,因为在导出jar时,不包括src文件夹。 So if you create your own default package, then you'll have some defined root directory to base your resource paths on. 因此,如果您创建自己的默认包,那么您将拥有一些已定义的根目录,以基于您的资源路径。

After you've created your own default package, your problem might already be fixed, but if it wasn't then try this: 在您创建了自己的默认包之后,您的问题可能已经修复,但如果不是,请尝试以下操作:

YourClass.class.getResource("/your_root_package/blah/blah/file.glsl");

It works for me for images: 它适用于我的图像:

public static Image ICON32 = Toolkit.getDefaultToolkit().getImage(MainFrame.class.getResource("/files/images/icon32.png"));

Yeah, so, hope this helps. 是的,所以,希望这会有所帮助。 :) :)

The problem is actually this line: 问题实际上是这一行:

protected static char c = File.separatorChar;

This will be a backslash on Windows, but paths for Class#getResource() must be forward slashes in order to work correctly. 这将是Windows上的反斜杠,但Class#getResource()路径必须是正斜杠才能正常工作。 The JRE is probably looking for your path as a relative path and interpreting the backslash literally. JRE可能正在寻找您的路径作为相对路径并从字​​面上解释反斜杠。

In any case, what you should be using for this particular example is: 在任何情况下,您应该为此特定示例使用的是:

URL out = getClass().getResource("file.glsl");

Class#getResource() already handles resolving this relative to the class, so it doesn't make sense to duplicate that code in your app. Class#getResource()已经处理了相对于类的解析,因此在应用程序中复制该代码没有意义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM