Jar无法加载包含类文件的文件夹

时间:2017-05-31 18:46:02

标签: java exception classpath jython executable-jar

我正在与Jython一起制作Maven项目。在Eclipse中运行正常,但是当我运行导出的jar时,它会产生异常。

这是src/main/resources内的目录:

src/main/resources:
    mylib
        file_one.py
        file_two.py
    pylib
        sys.py
        sys$py.class
        os.py
        os$py.class
        ...

我一直在尝试使用以下代码片段加载包含pylib中的类文件的文件夹src/main/resources

public class MyClass {

    // ...

    public static void init() {
        // ...
        ClassLoader classLoader = Prompt.class.getClassLoader();
        addToPath(path, classLoader.getResource("mylib").getPath());
        System.out.println("Found mylib");
        addToPath(path, classLoader.getResource("pylib").getPath());
        System.out.println("Found pylib");
        // ...
    }

    // ...

}

导出到jar 时出现此错误

JAR export finished with warnings. See details for additional information.
  Problem writing project/src/main/resources/.DS_Store to JAR: duplicate entry: .DS_Store
  duplicate entry: .DS_Store

我多次测试过,但jar只包含了不包含类文件的文件夹mylib。如果我包含pylib,我收到此错误:

java.lang.NullPointerException
    at *project*.Prompt.init(Prompt.java:53)
    at *project*.Prompt.start(Prompt.java:76)
    at *project*.Main.main(Main.java:6)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
  

注意:   我用*package*替换了我的组ID以隐藏我的项目的身份。

有谁知道如何加载类文件?

  

编辑:

     
      
  • 通过添加分号更正代码。
  •   
  • 添加println表达式以明确执行jar失败的位置。
  •   
  • 添加了路径信息。
  •   
  • 更改了班级和项目名称。
  •   
  • 添加了导出错误。
  •   
  • 扩展的运行时错误
  •   

1 个答案:

答案 0 :(得分:0)

问题必须是JAR文件的创建方式或内容。

我刚刚完成了一个最小的完整样本。适用于Eclipse,Windows命令提示符,Git Bash和SUSE Linux!

目录结构:

./bin
./bin/classes
./bin/classes/project
./bin/classes/project/Prompt.class
./bin/classes/pylib
./bin/classes/pylib/file.txt
./py.jar
./py.jardesc
./src
./src/java
./src/java/project
./src/java/project/Prompt.java
./src/java/pylib
./src/java/pylib/file.txt

Prompt.java:

package project;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class Prompt {

    public static void main(String[] args) {
        ClassLoader cl = Prompt.class.getClassLoader();
        URL url;
        url = cl.getResource("pylib");
        System.out.println(url);

        url = cl.getResource("pylib/file.txt");
        System.out.println(url);
        try (InputStream in = url.openStream()) {
            int ch;
            while ((ch = in.read()) != -1) {
                System.out.print((char) ch);
            }
            System.out.println();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

file.txt(用于测试):

Just a test

由Eclipses JAR导出向导创建的JAR具有以下设置:

  1. 选择要导出的资源:"项目" 和" pylib" 目录
  2. 激活"导出生成的类文件和资源
  3. 选择选项"添加目录条目"
  4. 选择"生成清单文件"
  5. 进入" project.Prompt"作为主要课程
  6. JAR的内容是(第一行是提示和生成该列表的命令):

    $ jar -tvf py.jar
        53 Fri Jun 02 07:42:02 UTC 2017 META-INF/MANIFEST.MF
         0 Fri Jun 02 07:34:10 UTC 2017 pylib/
        11 Fri Jun 02 07:34:20 UTC 2017 pylib/file.txt
         0 Fri Jun 02 07:36:34 UTC 2017 project/
      1480 Fri Jun 02 07:41:54 UTC 2017 project/Prompt.class
    

    执行人:

    1. Eclipse:以>运行Java应用程序
    2. DOS /命令提示符:java -jar py.jar
    3. DOS /命令提示符:java -cp py.jar project.Prompt
    4. Git Bash:java -jar py.jar
    5. Git Bash:java -cp py.jar project.Prompt
    6. SUSE Linux,不同的计算机,空文件夹:java -jar py.jar
    7. SUSE Linux,不同的计算机,空文件夹:java -cp py.jar project.Prompt
    8. 它为所有上述情况生成几乎相同的输出,只是路径不同:

        

      蚀:

      file:/C:/DEVELOP/ECLIPSE/test/bin/classes/pylib
      file:/C:/DEVELOP/ECLIPSE/test/bin/classes/pylib/file.txt
      Just a test
      
           

      DOS提示符,Git Bash:

      jar:file:/C:/DEVELOP/ECLIPSE/test/py.jar!/pylib
      jar:file:/C:/DEVELOP/ECLIPSE/test/py.jar!/pylib/file.txt
      Just a test
      
           

      SUSE Linux:

      jar:file:/home/user/pytest/py.jar!/pylib
      jar:file:/home/user/pytest/py.jar!/pylib/file.txt
      Just a test
      

      在Windows上使用Java 8进行编译和执行;在SUSE Linux上使用Java 9执行。