使用classpath参数运行jar

时间:2014-06-03 14:43:30

标签: java jar classpath


我可能会错过一些愚蠢但仍然存在的东西 我创建了一个具有以下内部结构的jar文件:

  • folder1中
  • 文件夹2
  • META-INF
  • 资源

其中folder1和folder2保存.class文件和资源有txt和png文件 在我的代码中,我有以下行

BufferedReader reader = new BufferedReader(new InputStreamReader(
                ClassLoader.getSystemResourceAsStream(txtFile)));

其中txtFile是一个字符串,其中包含位于资源文件夹中的文件名。 (直接在文件夹中)。
问题是当我尝试从命令行运行程序时 这是我跑的命令。

java -cp externalJar.jar;myJar.jar;resources com.my.package.MyMainClass

程序运行和精细单元我到达上面的代码行,我得到一个空指针异常:

java.lang.NullPointerException
at java.io.Reader.<init>(Unknown Source)
at java.io.InputStreamReader.<init>(Unknown Source)
at com.my.package.MyMainClass.generateSomething(Unknown Source)
at com.my.package.MyMainClass.main

我猜这意味着我的类路径有问题 - 但我无法想象...

修改
我正在使用ant编译程序并将程序打包到一个可执行的jar中 这是我build.xml

的一部分
<target name="jar" depends="compile">
    <jar destfile="${executable.jar}" basedir="${bin}">
        <zipfileset dir="${src}\resources" prefix="resources" />
        <manifest>
            <attribute name="Main-Class" value="MyMainClass" />
            <attribute name="Class-Path" value="externalJar.jar" />
        </manifest>
    </jar>
</target>

编辑 - 2
因为它应该是一个可执行jar,所以txtFile变量的值是硬编码的(除非作为参数给出)作为资源目录中的文件名。所以最终,我想运行这个命令:
java -jar myJar.jar
不幸的是 - 这也导致了相同的方式(同一行上的NullPointerException)
编辑 - 3(发现非优雅解决方案)
我发现如果我连接到类加载器读取的文件的所有路径前缀"resources/"然后它工作正常 - 但我发现这是不优雅的。有没有办法将资源文件夹添加到类路径?

2 个答案:

答案 0 :(得分:2)

首先,如果您只打算访问与MyMainclass位于同一个jar中的文件,则可以在其类加载器而不是{{1}上调用getResource()getResourceAsStream() } / getSystemResource()

getSystemResourceAsStream()

其次,您应该将路径传递给文件,而不是在类路径上传递resources文件夹:

public class MyMainClass {

    public static void main(String[] args) throws Exception {
        InputStream inputStream = MyMainClass.class.getResourceAsStream(args[0]);
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
    }
}

请注意,在创建InputStreamReader时指定编码(几乎)总是一个好主意,否则您依赖于JVM默认编码。

答案 1 :(得分:-1)

有一件事是清楚的,txtFile变量将是null或不存在的路径,因为NPE源自那里。

OR

问题的另一个可能性是调用ClassLoader.getSystemResourceAsStream(txtFile)

为了让正确的加载程序访问您的资源,请将其更改为

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getSystemResourceAsStream(txtFile);

并使用该流。