可执行jar将找不到属性文件

时间:2010-11-08 16:53:38

标签: java eclipse jar maven

我在程序中使用此代码来加载属性文件:

Properties properties = new Properties();
URL url = new App().getClass().getResource(PROPERTIES_FILE);
properties.load(url.openStream());

代码在Eclipse中运行良好。然后我将程序打包成一个名为MyProgram.jar的JAR,并运行它,我在第二行得到一个NullPointerException。 JAR不包含属性文件,它们都在同一目录中。我正在使用Maven来创建JAR。我该如何解决这个问题?

更新:我不想将属性文件添加到JAR,因为它将在部署时创建。

5 个答案:

答案 0 :(得分:23)

BalusC是对的,您需要指示Maven使用MANIFEST.MF条目中的当前目录(.)生成Class-Path:

假设您仍在使用Maven Assembly Plugin和jar-with-dependencies描述符来构建可执行JAR,您可以使用以下命令告诉插件:

  <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>com.stackoverflow.App</mainClass>
        </manifest>
        <manifestEntries>
          <Class-Path>.</Class-Path> <!-- HERE IS THE IMPORTANT BIT -->
        </manifestEntries>
      </archive>
    </configuration>
    <executions>
      <execution>
        <id>make-assembly</id> <!-- this is used for inheritance merges -->
        <phase>package</phase> <!-- append to the packaging phase. -->
        <goals>
          <goal>single</goal> <!-- goals == mojos -->
        </goals>
      </execution>
    </executions>
  </plugin>

答案 1 :(得分:18)

有两个解决方法

  1. 不要将JAR用作executabele JAR,而应用作库。

    java -cp .;filename.jar com.example.YourClassWithMain
    
  2. 获取JAR文件的根位置并从中获取属性文件。

    URL root = getClass().getProtectionDomain().getCodeSource().getLocation();
    URL propertiesFile = new URL(root, "filename.properties");
    Properties properties = new Properties();
    properties.load(propertiesFile.openStream());
    
  3. 两者都不是推荐的方法!建议的方法是在JAR的/META-INF/MANIFEST.MF文件中包含以下条目:

    Class-Path: .
    

    然后它将以通常的方式作为类路径资源使用。你真的必须以某种方式指示Maven生成MANIFEST.MF这样的文件。

答案 2 :(得分:2)

编辑:这是为了回复你的评论:

您需要确保属性文件位于具有正确根目录的类路径上,以便对jar文件进行加注。如果你的路径是

stuff / things.properties

,运行时位置为

/opt/myapp/etc/stuff/things.properties

并且jar文件在

/ opt / myapp / bin / myjar

然后你需要以

启动

/ path / to / java -cp“/opt/myapp/etc:/opt/myapp/bin/myjar.jar"my.pkg.KavaMain

使用这种配置在开发环境中可能会很烦人,幸运的是,maven exec plugin可以为您提供正确的启动方案。

原始答案:

您想了解the maven resources plugin

基本上你想要添加这样的东西:

<plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
                <resources>
                        <resource>
                                <directory>src/main/java</directory>
                                <includes>
                                        <include>**/*properties</include>
                                </includes>
                        </resource>
                </resources>
        </configuration>
<plugin>

到你的pom.xml,假设你的属性文件是你的java源代码 - 真的应该在src / main / resources中。

答案 3 :(得分:0)

我有类似的问题,这个帖子是一个很大的帮助!仅供参考,我修改了我的Ant构建文件以进行MANIFEST制作,然后在JAR-ing我的服务器端代码时指定显示:

<!-- Create a custom MANIFEST.MF file, setting the classpath. -->
<delete file="${project.base.dir}/resources/MANIFEST.MF" failonerror="false"/>
<manifest file="${project.base.dir}/resources/MANIFEST.MF">
  <attribute name="Class-Path" value="." />
</manifest>

<!-- JAR the server-side code, using the custom manifest from above. -->
<jar destfile="services/${name}.aar" manifest="${project.base.dir}/resources/MANIFEST.MF">
[....]

答案 4 :(得分:-3)

感谢所有这些代码,对我而言,此URL获得了我们可运行的jar位置 如此容易,我必须读取我的属性文件,因此将您的属性文件放在可运行的jar文件位置

URL root = getClass().getProtectionDomain().getCodeSource().getLocation();
URL propertiesFile = new URL(root, "filename.properties");
Properties properties = new Properties();
properties.load(propertiesFile.openStream());