简体   繁体   English

Jar 没有加载资源文件

[英]Jar is not loading resources file

I have a project with a folder "src/main/resources" where inside there is the hibernate configuration file, I load it using this line of code我有一个项目,其中有一个文件夹“src/main/resources”,其中有休眠配置文件,我使用这行代码加载它

HibernateUtil.class.getResource("/hibernate.cgf.xml").getPath()

From inside the IDE it is working well, but when I create the jar it doesn't file the file.从 IDE 内部它运行良好,但是当我创建 jar 时它不会归档文件。

How can I load it properly in the jar file too?我怎样才能在jar文件中正确加载它?

Thanks谢谢

Could you please try this:你能试试这个:

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("fileName").getFile());

I cannot say for ceratin that this is the issue without knowing how exactly you use the path extracted by:在不知道您如何准确使用通过以下方式提取的路径的情况下,我不能说这是问题所在:

HibernateUtil.class.getResource("/hibernate.cgf.xml").getPath()

but I can tell you this:但我可以告诉你:

Run from an IDE the above line of code will return:从 IDE 运行,上面的代码行将返回:

/path/to/project/src/main/resources/hibernate.cgf.xml

which is a valid filesystem path.这是一个有效的文件系统路径。 You can then use this path to, for example, create an instance of File class and then use that instance to read the file contents.例如,您可以使用此路径创建File类的实例,然后使用该实例读取文件内容。

However the same line of code run from inside a jar file will return:但是,从 jar 文件内部运行的同一行代码将返回:

file:/path/to/jar/jar_name.jar!/hibernate.cgf.xml

which is not a valid filesystem path.这不是有效的文件系统路径。 If you create an instance of File class using this path and then try to read the contents of the file you'll get an exception: java.io.FileNotFoundExeption如果您使用此路径创建File类的实例,然后尝试读取文件的内容,您将得到一个异常: java.io.FileNotFoundExeption

To read the contents of the file from inside of a jar you should use method Class.getResourceAsStream(String) , which will return an instance of class sun.net.www.protocol.jar.JarURLConnection.JarURLInputStream (or equivalent in non-Oracle or non-OpenJDK Java).要从 jar 中读取文件的内容,您应该使用方法Class.getResourceAsStream(String) ,它将返回类sun.net.www.protocol.jar.JarURLConnection.JarURLInputStream的实例(或非 Oracle 中的等价物或非 OpenJDK Java)。 You can then use this object to read the contents of the file.然后,您可以使用此对象来读取文件的内容。 For example:例如:

InputStream inputStream = HibernateUtil.class.getResourceAsStream("/hibernate.cgf.xml");
Scanner scanner = new Scanner(inputStream).useDelimiter("\\A");
String fileContents = scanner.hasNext() ? sscanner.next() : "";

Most likely, the file is absent from the jar you create.最有可能的是,您创建的 jar 中不存在该文件。 There's too little information in your question, but I will try a guess:您的问题中的信息太少,但我会尝试猜测:

Your hibernate.cgf.xml resides in the same directory as the Java sourcefles, and you are using a build tool (be it IDE, maven, gradle or an ant script) that expects resources to be stored in a separate directory.您的 hibernate.cgf.xml 与 Java 源文件位于同一目录中,并且您正在使用期望资源存储在单独目录中的构建工具(无论是 IDE、maven、gradle 还是 ant 脚本)。

It's easy to check: try to unzip your jar and see if the file is there (use any tool, you can just change the extension from .jar to .zip).很容易检查:尝试解压缩您的 jar 并查看文件是否存在(使用任何工具,您可以将扩展名从 .jar 更改为 .zip)。 I think you will see the file is absent.我想你会看到文件不存在。

Then come back with a question: "how to pack my non-java resources into a jar, using XXX", where XXX will be the name of the techology you are using for building the jar.然后回到一个问题:“如何使用 XXX 将我的非 Java 资源打包到 jar 中”,其中 XXX 将是您用于构建 jar 的技术的名称。

Most probably the slash in "/hibernate.cgf.xml" is not needed, if the hibernate.cgf.xml is in the same package as you class HibernateUtil.如果hibernate.cgf.xml与 HibernateUtil 类在同一个包中,则很可能不需要"/hibernate.cgf.xml"中的斜线。

You can access the file actually also via the classloader using the full path.您实际上也可以使用完整路径通过类加载器访问该文件。 Yet you never add to it the first slash.但是,您永远不会添加第一个斜线。

Here is some code demonstrating how you can access the file using different methods:下面是一些代码,演示了如何使用不同的方法访问文件:

public static void main(String[] args) {
    // Accessing via class
    System.out.println(SimpleTests.class.getResource("hibernate.cgf.xml").getPath());
    // Accessing via classloader from the current thread
    String path = Thread.currentThread().getContextClassLoader()
            .getResource("simple/hibernate.cgf.xml").getPath();
    System.out.println(path);
    // Accessing via classloader used by the current class
    System.out.println(SimpleTests.class.getClassLoader().getResource("simple/hibernate.cgf.xml").getPath());
}

In the example above the package 'simple' should be replaced by the package where your hibernate.cgf.xml is.在上面的示例中,“simple”包应该替换为hibernate.cgf.xml所在的包。 But you should never have the slash at the beginning of the package declaration.但是你不应该在包声明的开头有斜线。

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

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