0

Cuurent state As chris suggested i created a minimum example (maven based):

public class MainApp {
    public static void main(String[] args) {
        System.out.println(MainApp.class.getResourceAsStream("/my.properties"));
        System.out.println(MainApp.class.getClassLoader().getResourceAsStream("their.properties"));
    }
}

This is working (same maven config as in my not working app, and same MANIFEST.MF in same location )! So i just copied the 2 lines from above into my real app, built it and copied the 2 files into jar's folder. but now both sysouts yield "null"! So something seems to fiddling around with classpath/ or let ignore classpath from manifest? (the output from printing out class path is same in both cases - only the jar is printed out) Any idea how to nail down the problem?

original question:

I have problem to read a file (properties) from current directory. Here is my setup (maven based): reading of file:

MyClass.class.getClassLoader().getResourceAsStream("my.properties")

Works fine within tests an my properties placed in resources/my.properties.

Since the current directory is the default classpath i thought it should just work to put my.properties in same directory as jar and run java -jar from this directory, but it didn't work (resource stream is null). Then i added odd code to main to print out class path:

String classpath = System.getProperty("java.class.path");
String[] classpathEntries = classpath.split(File.pathSeparator);
for (int i = 0; i < classpathEntries.length; i++) {
    System.out.println(classpathEntries[i]);
}

I also tried some other code but in both cases only my jar file's path was printed out. So i tried to add '.' to Manifest by using maven assembly plugin. From manifest:

...
Class-Path: .
...

But this didn't helped. So how to get my program load getClassLoader().getResourceAsStream(my.properties) from current directory?

Why this is not a duplicate of this I have no problem to load the resource from classpath. i put the file in src/test/resource/my.properties Maven copies them together with all classes and all is working fine. Since the file is in src/test/resources it is missing in packaged jar (as intended). The user must give a my.properties to run the program. And i want to read this file from current directory (assuming that java - jar is called from directory with jar an my.properties) but this isn't working!

EDIT maven-assembly-plugin config:

        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
            <archive>
                <manifest>
                    <mainClass>some.pkg.MainApp</mainClass>
                </manifest>
                <manifestEntries>
                    <Class-Path>.</Class-Path>
                </manifestEntries>
            </archive>
        </configuration>

This results in manifest ...jar/META-INF/MANIFEST.MF

Community
  • 1
  • 1
dermoritz
  • 12,519
  • 25
  • 97
  • 185
  • you need a `String` in `getResourceAsStream("my.properties")` – JNL Jun 25 '14 at 14:19
  • the "maven" way of adding a resource is to add it to /src/main/resources. Maven will then put in the right place so that the getClassLoader().getResourceAsStream("/my.properties") will work the way you expect – Gus Jun 25 '14 at 14:39
  • my problem is it walked the maven way, it all works fine within test because the my.properties is in right place (src/test/resources). but the file is not found on run time if it is placed in current directory (the user is forced to deliver one, no default provided) – dermoritz Jun 25 '14 at 14:44

1 Answers1

1

Running Java 1.7.0_51-b13 (Oracle) on Ubuntu, your approach worked fine for me. So there is either a difference introduced by versions or a subtle twist in how you are running your test. Here is how I ran my test, perhaps it will help you to diagnose further.

Here is the Manifest that I used

Manifest-Version: 1.0
Class-Path: .
Main-Class: Foo
Created-By: 1.7.0_06 (Oracle Corporation)

And the code

public class Foo {

    public static void main( String[] args ) {
      Object v = Foo.class.getClassLoader().getResourceAsStream("my.properties");

      System.out.println( "v = " + v );
    }
}

I created the jar as follows:

jar cfm MyJar.jar Manifest.txt Foo.class

I then moved the jar into its own directory and ran

cd dirContainingJar
java -jar MyJar.jar

and it printed null, so I then

echo Hello > my.properties
java -jar MyJar.jar

and it printed

v = java.io.BufferedInputStream@131b92e6
Chris K
  • 11,622
  • 1
  • 36
  • 49
  • i am using maven - i will try to create a minimal example with maven... let's see – dermoritz Jun 25 '14 at 14:47
  • Using Maven or not should not matter, so long as the jar file being created is correct. It would be worth opening that jar file up and inspecting it by eye. Specifically the MANIFEST.MF file; it is possible that that is not getting picked up correctly for you. Make sure that you are using the maven manifest tags, and not just including the file under resources. – Chris K Jun 25 '14 at 14:50
  • i updated my question, but i think all is fine with manifest because calling main is working fine (Main class is specified there to) – dermoritz Jun 25 '14 at 15:03
  • I knocked up a pom.xml using the spec that you gave above, and that also produced a jar file that ran for me. This is sounding increasingly to be version/environmental. – Chris K Jun 25 '14 at 15:23
  • Side stepping the initial problem slightly, and thinking of alternative approaches to achieve your end goal. Have you considered using Properties.load instead? That is less likely to be so quirky. You can then use the system property user.dir to get the users current directory. – Chris K Jun 25 '14 at 15:38
  • i am using Properties.load but i am putting in the Inputstream. And i want this to work within tests (resources in src/test/resources) and in normal environment - properties in current dir. But thanks chris - in meantime i created a minimum example that is working. Now i am hunting the difference and probably i will find it... – dermoritz Jun 25 '14 at 15:42