I have something like this as Code, and it works fine but how
but i want replace the absolute path with System.getProperty("user.dir");
but this gives me back a string with backslahses how can i resolve it,
or replace this so that converts this to c:/........
public static void main(String[] args) throws Exception{
String strPropertiePath=System.getProperty("user.dir");
System.out.println("strPropertiePath "+strPropertiePath);
String absoluthPath2Propertie = "C:/Users/maurice/Dropbox/a_projectturkey/solution_06_09_2014/Application_Propertie/logging.properties";
File fileLog = new File(absoluthPath2Propertie);
LogManager.getLogManager().readConfiguration(new FileInputStream(absoluthPath2Propertie));
//ConfigSystem.setup();
}
}
Just use File or Path objects with proper parent-child relations. You do not need to care about slashes and blackslashes, File and Path will take care about them for you.
E.g. to define a property file which sits in the user dir folder in a subfolder of props and having a file name myprops.properties, you can use it like this:
File propFile = new File(System.getProperty("user.dir"),
"/props/myprops.properties");
And you can load this property file like this:
// Use try-with-resources to properly close the file input stream
try (InputStream in = new FileInputStream(propFile)) {
LogManager.getLogManager().readConfiguration(in);
}
Edit:
So if you need a file named logging.properties in your user dir, simply use this:
File propFile = new File(System.getProperty("user.dir"),
"logging.properties");
try (InputStream in = new FileInputStream(propFile)) {
LogManager.getLogManager().readConfiguration(in);
}
Use the following code to load the property file.
Properties properties=new Properties();
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
properties.load(in);
properties.get("user.dir");
You can get the system filesystem path delimiter with the following piece of code:
System.getProperties("file.separator")
By using this you will be able to create a correct path on any supported platform. Such that you can use slashes in UNIX/Linux based systems and backslashes on Windows.
Related
We have a spring boot application which has a legacy jar api that we use that needs to load properties by using InputFileStream. We wrapped the legacy jar in our spring boot fat jar and the properties files are under BOOT-INF/classes folder. I could see spring loading all the relevant properties but when I pass the properties file name to the legacy jar it could not read the properties file as its inside the jar and is not under physical path. In this scenario how do we pass the properties file to the legacy jar?
Please note we cannot change the legacy jar.
Actually you can, using FileSystem. You just have to emulate a filesystem on the folder you need to get the file from. For example if you wanted to get file.properties, which is under src/main/resources you could do something like this:
FileSystem fs = FileSystems.newFileSystem(this.getClass().getResource("").toURI(), Collections.emptyMap());
String pathToMyFile = fs.getPath("file.properties").toString();
yourLegacyClassThatNeedsAndAbsoluteFilePath.execute(pathToMyFile)
I also have faced this issue recently. I have a file I put in the resource file, let's call it path and I was not able to read it. #madoke has given one of the solutions using FileSystem. This is another one, here we are assuming we are in a container, and if not, we use the Java 8 features.
#Component
#Log4j2
public class DataInitializer implements
ApplicationListener<ApplicationReadyEvent> {
private YourRepo yourRepo; // this is your DataSource Repo
#Value(“${path.to.file}”). // the path to file MUST start with a forward slash: /iaka/myfile.csv
private String path;
public DataInitializer(YourRepo yourRepo) {
this.yourRepo = yourRepo;
}
#Override
public void onApplicationEvent(ApplicationReadyEvent event) {
try {
persistInputData();
log.info("Completed loading data");
} catch (IOException e) {
log.error("Error in reading / parsing CSV", e);
}
}
private void persistInputData() throws IOException {
log.info("The path to Customers: "+ path);
Stream<String> lines;
InputStream inputStream = DataInitializer.class.getClassLoader().getResourceAsStream(path);
if (inputStream != null) { // this means you are inside a fat-jar / container
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
lines = bufferedReader.lines();
} else {
URL resource = this.getClass().getResource(path);
String path = resource.getPath();
lines = Files.lines(Paths.get(path));
}
List<SnapCsvInput> inputs = lines.map(s -> s.split(","))
.skip(1) //the column names
.map(SnapCsvInput::new)
.collect(Collectors.toList());
inputs.forEach(i->log.info(i.toString()));
yourRepo.saveAll(inputs);
}
}
Basically, you can't, because the properties "file" is not a file, it's a resource in a jar file, which is compressed (it's actually a .zip file).
AFAIK, the only way to make this work is to extract the file from the jar, and put it on your server in a well-known location. Then at runtime open that file with an FileInputStream and pass it to the legacy method.
According to #moldovean's solution, you just need to call 'getResourceAsStream(path)' and continue with returned InputStream. Be aware that the 'path' is based on ClassPath. For example:
InputStream stream = this.getClass().getResourceAsStream("/your-file.csv");
In root of your class path, there is a file named 'your-file.csv' that you want to read.
I have a file which contain several paths, like . (relative) or /Users/...../ (absolut). I need to parse the paths that are relative to the directory of the file that contains the paths and not the working-directory and create correct File-instances. I can not change the working directory of the Java-Program, since this would alter the behaviour of other components and i also have to parse several files. I don't think public File(String parent, String child)does what i want, but i may be wrong. The documentation is quite confusing.
Example:
file xy located under /system/exampleProgram/config.config has the following content:
.
/Users/Name/file
./extensions
i want to resolve these to:
/system/exampleProgram/
/Users/Name/file
/system/exampleProgram/file/
So, I am going to assume that you have access to the path of the file you opened (either via File.getAbsolutePath() if it was a File descriptor or via a regex or something)...
Then to translate your relative paths into absolute paths, you can create new File descriptions with your opened file, like so:
File f = new File(myOpenedFilePath);
File g = new File(f, "./extensions");
String absolutePath = g.getCanonicalPath();
When you create a file with a File object and a String, Java treats the String as a path relative to the File given as a first argument. getCanonicalPath will get rid of all the redundant . and .. and such.
Edit: as Leander explained in the comments, the best way to determine whether the path is relative or not (and thus whether it should be transformed or not) is to use file.isAbsolute().
Sounds like you probably want something like
File fileContainingPaths = new File(pathToFileContainingPaths);
String directoryOfFileContainingPaths =
fileContainingPaths.getCanonicalFile().getParent();
BufferedReader r = new BufferedReader(new FileReader(fileContainingPaths));
String path;
while ((path = r.readLine()) != null) {
if (path.startsWith(File.separator)) {
System.out.println(path);
} else {
System.out.println(directoryOfFileContainingPaths + File.separator + path);
}
}
r.close();
Don't forget the getCanonicalFile(). (You might also consider using getAbsoluteFile()).
I have created a java project in which I am using a properties file also which is created inside a java packgae named abcedf
so package name is abcdef which consists a class name abc.java and a property file named drg.properties ,now from class abc.java i am referring to that properties file as..
abc tt = new abc();
URL url = tt.getClass().getResource("./drg.properties");
File file = new File(url.getPath());
FileInputStream fileInput = new FileInputStream(file);
now this file is referred and my program runs successfully but when I am trying to make it executable jar then this property file is not referred
please advise what is went wrong while creating the property file.
Use
tt.getClass().getResourceAsStream("./drg.properties");
to access the property file inside a JAR. You will get an InputStream as returned object.
-------------------------------------------------
Here is an example to load the InputStream to Properties object
InputStream in = tt.getClass().getResourceAsStream("./drg.properties");
Properties properties = new Properties();
properties.load(in); // Loads content into properties object
in.close();
If your case, you can directly use, the InputStream instead of using FileInputStream
When you access "jarred" resource you can't access it directly as you access a resource on your HDD with new File() (because resource doesn't live uncompressed on your drive) but you have to access resource (stored in your application jar) using Class.getResourceAsStream()
Code will looks like (with java7 try-with-resource feature)
Properties p = new Properties();
try(InputStream is = tt.getClass().getResourceAsStream("./drg.properties")) {
p.load(is); // Loads content into p object
}
I want to take place database.properties outside the project, so when I want to change the content (database configuration) of that when I've build them into jar, I can do it easily without open my project again. So what to do?
First, place the database.properties file in the location you'd like it to be in.
Then, do one of the following:
Add the directory where database.properties is located, to the classpath. Then use Thread.currentThread().getContextClassLoader().getResource() to get a URL to the file, or getResourceAsStream() to get an input stream for the file.
If you don't mind your Java application knowing the exact location of the database.properties file, you can use simple File I/O to obtain a reference to the file (use new File(filename)).
Usually, you'd want to stick with the first option. Place the file anywhere, and add the directory to the classpath. That way, your Java application doesn't have to be aware of the exact location of the file - it will find it as long as the file's directory is added to the runtime classpath.
Example (for the first approach):
public static void main(String []args) throws Exception {
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("database.properties");
Properties props = new Properties();
try {
// Read the properties.
props.load(stream);
} finally {
// Don't forget to close the stream, whatever happens.
stream.close();
}
// When reaching this point, 'props' has your database properties.
}
Store properties file in your preferred location. Then do the following:
try {
String myPropertiesFilePath = "D:\\configuration.properties"; // path to your properties file
File myPropFile = new File(myPropertiesFilePath); // open the file
Properties theConfiguration = new Properties();
theConfiguration.load(new FileInputStream(myPropFile)); // load the properties
catch (Exception e) {
}
Now you can easily get properties as String from the file:
String datasourceContext = theConfiguration.getString("demo.datasource.context", "jdbc/demo-DS"); // second one is the default value, in case there is no property defined in the file
Your configuration.properties file might look something like this:
demo.datasource.context=jdbc/demo-DS
demo.datasource.password=123
Is there a way to read the content of a file (maven.properties) inside a jar/war file with Java? I need to read the file from disk, when it's not used (in memory). Any advise on how to do this?
Regards,
Johan-Kees
String path = "META-INF/maven/pom.properties";
Properties prop = new Properties();
InputStream in = ClassLoader.getSystemResourceAsStream(path );
try {
prop.load(in);
}
catch (Exception e) {
} finally {
try { in.close(); }
catch (Exception ex){}
}
System.out.println("maven properties " + prop);
One thing first: technically, it's not a file. The JAR / WAR is a file, what you are looking for is an entry within an archive (AKA a resource).
And because it's not a file, you will need to get it as an InputStream
If the JAR / WAR is on the
classpath, you can do SomeClass.class.getResourceAsStream("/path/from/the/jar/to/maven.properties"), where SomeClass is any class inside that JAR / WAR
// these are equivalent:
SomeClass.class.getResourceAsStream("/abc/def");
SomeClass.class.getClassLoader().getResourceAsStream("abc/def");
// note the missing slash in the second version
If not, you will have to read the JAR / WAR like this:
JarFile jarFile = new JarFile(file);
InputStream inputStream =
jarFile.getInputStream(jarFile.getEntry("path/to/maven.properties"));
Now you probably want to load the InputStream into a Properties object:
Properties props = new Properties();
// or: Properties props = System.getProperties();
props.load(inputStream);
Or you can read the InputStream to a String. This is much easier if you use a library like
Apache Commons / IO
String str = IOUtils.toString(inputStream)
Google Guava
String str = CharStreams.toString(new InputStreamReader(inputStream));
This is definitely possible although without knowing your exact situation it's difficult to say specifically.
WAR and JAR files are basically .zip files, so if you have the location of the file containing the .properties file you want you can just open it up using ZipFile and extract the properties.
If it's a JAR file though, there may be an easier way: you could just add it to your classpath and load the properties using something like:
SomeClass.class.getClassLoader().getResourceAsStream("maven.properties");
(assuming the properties file is in the root package)