Where should application.properties file get stored? - java

In a java project where does the application.properties file commonly get stored?

I store my application properties in src.main.resources. Resources package is quite self-explanatory and property files can be easily found there for everyone who looks at this project for the first time. Resouces are stored in main package in case you need different configuration for your tests, therefore I have also src.test.resources package.

In a JAVA project you can keep the properties files wherever you want, as long as you can find them during runtime.
Take a look at this question for more details: Loading a properties file from Java package
For a MAVEN project:
You can of course override this, but normally properties files in maven projects are kept in specific places:
Configuration used during runtime is kept in src/main/resources.
Configuration used during tests is kept in src/test/resources.

Related

Difference between classpath:/some/packages vs file:/some/url when configuring Spring Boot

I'm learning Spring Boot and sometimes I have to config application.properties with values like classpath:/some/packages and file:/some/url. What is the difference between classpath vs file in this situation ?
Firstly, you need to understand what the classpath is. Here is a good answer about it:
It would be impractical to have the VM look through every folder on your machine, so you have to provide the VM a list of places to look. This is done by putting folder and jar files on your classpath.
Shortly, classpaths contain:
JAR files of your project
and Paths to the top of package hierarchies.
So when you have classpath:/some/packages - think of it as you point to a file inside your project (the first / is the root for the compiled classes and resources). But when you have file:/some/url you point to a file anywhere in the OS.

JUnit5: Where is the root of #CsvFileSource defined and can that definition be changed to refer to a different directory?

I started a project as a maven-quickstart and added JUNIT5.
There was no 'resources' folder anywhere. It builds using a pom.xml and up to "package" goal.
Some time after, one of the testers wanted to add a test that reads from a CSV file.
He had some trouble setting up and I recalled from just memory that it will look in test/resources.
We are all fine now but I just can't stop wondering: Is 'test/resources' hard-coded into JUnit? Or is it somehow derived from the project archetype?
Is there a way to edit this reference in the project settings, vm settings or maybe in the very test method?
From https://junit.org/junit5/docs/5.3.0/api/org/junit/jupiter/params/provider/CsvFileSource.html
used to load comma-separated value (CSV) files from one or more classpath resources.
The way to load resources with this annotation (if they are not on the classpath) is to put them on the classpath.
So, to answer your question - yes you can change this setting by changing the classpath.
How you do that depends on what you are using to build, e.g.:
For java, you use java -cp ..., maven, gradle, ant all have different ways and since you have not posted a specific question we can't give a specific answer.
EDIT - Since you're using Maven - create a src/test/resources (or src/main/resources) and unless you're overriding the defaults Maven will automatically make those part of the test classpath (and classpath, respictively). Put your file in src/test/resources and it should work.

Any other approach instead of Properties file?

I have an legacy code base , which is built by using ant. I can see lot’s of properties file been used throughout the project, which gives deployment url and other things.
I certainly hate this approach. By any chance, we can remove these properties file and inject these values to Java classes at run time?
And I see most of the properties files are used in build.xml. Does other build tool handles these situation in ease?
Thanks in advance.

Mock a config file

I'm writing tests for an app that refers to a hardcoded filename "classpath:config.properties". It isn't possible to change this name. Is there any way to test this app with different configs? i.e. different tests supply different configs at runtime?
This is an odd requirement, but I'd deeply appreciate any inputs
Here is another question that might help you:
Dynamically loading properties file using Spring
Or you can always overwrite the properties file using the Java IO libraries.
It's all about classpath - what jars are in classpath and how you organize your project structure.
User maven so that resources from 'src/test/resources' are loaded before 'src/main/resources'. But generally the best way is to separate application-specific config resources from application code.
Alternatively, you can split the project with config resources into 3 or 4 projects:
project with code
project with config resources, added to app classpath, but not to test classpath
project with test resources, added to test classpath, but not to the app classpath
optionally, you can move JUnit test code to separate project
If you load your configuration from classpath:config.properties then these properties reside in src/main/resources folder.
When you run tests you can put your mock configuration in src/test/resources and it will "override" main configuration.

How are dependencies in multiple log4j.properties files managed under Maven?

I have a maven project with several dependencies and use log4j.properties to control output. In some cases the same class may be referenced in different property files with different parameters. Is there a defined protocol for "overriding" properties or does it depend on the order in which packages are loaded?
(I am locating all log4j.properties directly under src/main/resources - is this the correct place?)
UPDATE:
I have accepted #Assen's answer as it makes sense though it doesn't make the solution easy. Essentially he recommends excluding log4j.properties from the jar. In principle I agree, but it puts the burden on the user to control the output and most of my users don't know what Java is, let alone properties files.
Maybe there is a way of renaming the properties files in each jar and using a switch (maybe with -D) to activates the properties.
I often have similar discussions on projects. I thing log4j.properties is typically something you want to keep out of the application, and not pack it in a war and deliver it together with the code. Logging configuration:
is environment specific. When you write the application, you simply can't define the appenders that will be desired, file locations etc.
its lifecycle is totally different than the application's. After an application is deployed, logging properties can be changed several times a day. Redeploying the application shouldn't override your last logging settings.
Why package logging configuration together with your code then? I usually keep somewhere a configuration folder, with soubfolders like 'dev', 'test-server-01', 'macbook-john' etc. Each subfolder contains list own copy of log4j.properties. None of them is included in the build artifact - jar or war.
When deploying, one of thuse subfolders is delivered separately. For the test server 1, this would be the content of test-server-01 subfolder. Dependng on the application server used, thers is a different trick tu put some files on the classpath.
When developing, I take care to set one of those subfolders on the path. When John develops on his macbook, he might want to put 'macbook-jihn' on the classpath, or create a new one. He can change logging settings and commit without conflicts.

Categories