When I run main()
from IntelliJ I got as, expected peter,johnson
as result in standard out. But when I run mvn clean package
and try to execute java -jar target/example-1.0.0-SNAPSHOT-jar-with-dependencies.jar
I get following error message. Why and how can I make sure that .properties file is read?
java -jar target/example-1.0.0-SNAPSHOT-jar-with-dependencies.jar
Exception in thread "main" java.io.FileNotFoundException: file:/Users/ismar.slomic/src/ADOP/example/target/example-1.0.0-SNAPSHOT- jar-with-dependencies.jar!/my-example.properties (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at com.example.MyPropertiesClass.getFullName(MyPropertiesClass.java:18)
at com.example.MyMainClass.main(MyMainClass.java:9)
MyMainClass
package com.example;
import java.io.IOException;
public class MyMainClass {
public static void main(String[] args) throws IOException {
MyPropertiesClass mpc = new MyPropertiesClass();
System.out.println(mpc.getFullName());
}
}
MyPropertiesClass
package com.example;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class MyPropertiesClass {
public String getFullName() throws IOException {
Properties properties = new Properties();
ClassLoader cl = this.getClass().getClassLoader();
String filePath = cl.getResource("my-example.properties").getFile();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
properties.load(bis);
String name = properties.getProperty("name");
String lastname = properties.getProperty("lastname");
return name + "," + lastname;
}
}
my-example.properties
name=peter
lastname=johnson
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>example</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>My Example</description>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.example.MyMainClass</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
If your property file is inside your jar, then you'd better to use getResourceAsStream
instead of getResource
and getFile
.
Something like:
ClassLoader cl = this.getClass().getClassLoader();
try (InputStream stream = cl.getResourceAsStream("my-example.properties")) {
properties.load(bis);
}
The method getResource(String)
returns an URL that points to a file inside a jar. In your case, something like: file:/Users/ismar.slomic/src/ADOP/example/target/example-1.0.0-SNAPSHOT-jar-with-dependencies.jar!/my-example.properties
. When you call getFile
on that URL, it returns the file (i.e. the jar) which and not the pointer to the properties file inside.
What could also work is to open a connection on the URL and use the returned JarURLConnection
. But it is easier with getResourceAsStream
.