.properties as final static variable - java

I've got a .properties in my java project, that is updated by shell script.
I want to get this properties values and use it as final static variable. Here is my .properties code
WEBURL=http://popgom.fr
NODEURL=http://192.168.2.30:5555/wd/hub
I know I can get and use my .properties using this :
Properties prop = new Properties();
InputStream input = new FileInputStream("config.properties");
// load a properties file
prop.load(input);
String urlnode = prop.getProperty("NODEURL");
What I want to do is to get this String in every class of my project, without adding the code bellow in every classes.
How can I do this ? I've try to do an Interface, without success.
Any of you have an idea ?
Thanks for help

you can do it using Singleton pattern:
Example:
public class MyProperties{
private static MyProperties instance = null;
private Properties prop;
private MyProperties() {
InputStream input = new FileInputStream("config.properties");
// load a properties file
prop.load(input);
}
public static MyProperties getInstance() {
if(instance == null) {
instance = new MyProperties();
}
return instance;
}
public Properties getProperty() {
return prop;
}
}
You can invoke this code everywhere:
....
....
MyProperties.getInstance().getProperty();
....
....

Related

Reading database properties from property source not working

I want to read my database property values from the application.property file but not being able to.
I tried reading the properties from custom properties file but it didnt work. I don't want to hard code the properties as it will will be different in different servers.
#Configuration
#PropertySource("application.properties")
public class DatabaseUtils {
#Value("${mysql.drive}")
private static String MY_SQL_DRIVER;
#Value("${mysql.url}")
private static String MY_SQL_URL;
#Value("${mysql.username}")
private static String DATABASE_USERNAME;
#Value("${mysql.password}")
private static String DATABASE_PASSWORD;
public DatabaseUtils () {
}
#Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
public static ResultSet executeDBQuery(String query) {
try {
Class.forName(MY_SQL_DRIVER);
Connection connection = DriverManager.getConnection(MY_SQL_URL, DATABASE_USERNAME, DATABASE_PASSWORD);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
return resultSet;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
(properties file)
# database
databaseDriver=com.mysql.jdbc.Driver
databaseUrl=jdbc:mysql://localhost:3306/school
databaseUsername=root
databasePassword=root
I am new to spring-boot so getting a little confused as to why its not working, read a lot of online sources and tried them but didnt work, not sure what I am missing. Any help will be appreciated.
The properties in your property file is different from what you are giving in #Value.for eg. your property key is databaseDriver but you are giving mysql.drive in your code.
#Value("${mysql.drive}")
private static String MY_SQL_DRIVER;
But it should be
#Value("${databaseDriver}")
private static String MY_SQL_DRIVER;
basically what properties you define in the properties file should be referred in the application right. Here you are defining property as databaseDriver.
databaseDriver=com.mysql.jdbc.Driver
Then in code also you should ask for "databaseDriver"
#Value("${databaseDriver}")
private static String MY_SQL_DRIVER;

Spring JUnit ApplicationContextInitializer parameters

We have implemented an extended .properties format. Such a properties file can contain an optional include property. The value of this properties is the classpaths of other properties files to load recursively.
I could configure the Spring environment for my application but I have a problem to engage this mechanism with SpringJUnit4ClassRunner.
I thought I could use the initializer property of the ContextConfiguration annotation but it looks it can only be instantiated with a no-arg constructor.
I need to give it the root file of my properties files hierarchy. It could eventually be another annotation on my test class, but again, how can I access it ?
The only think I have found so far is to set this file as a system property in my test class static initializer. ugly?:
#ActiveProfiles("qacs.controller.channels=mock")
#ContextConfiguration(initializer=ContainerTestContextInitializer.class)
public class QacsControllerTest
{
static
{
System.setProperty(ContainerTestContextInitializer.SYSTEM_PROPERTY, "classpath:com/xxx/qacs/QacsControllerTest.properties");
}
#Test
void test() {}
}
}
public class ContainerTestContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
{
public static final String SYSTEM_PROPERTY = "icomp.test.properties";
#Override
public void initialize(ConfigurableApplicationContext pApplicationContext)
{
String path = System.getProperty(SYSTEM_PROPERTY);
if (path == null)
{
throw new IllegalStateException("Missing system property " + SYSTEM_PROPERTY);
}
final DefaultPropertiesLoader loader;
loader = new DefaultPropertiesLoader(System.getProperties());
try
{
loader.load(path);
}
catch (IOException e)
{
throw new IllegalStateException(e.getMessage(), e);
}
MutablePropertySources sources = pApplicationContext.getEnvironment().getPropertySources();
MapPropertySource mps = new MapPropertySource(Launcher.ICOMP_PROPERTY_SOURCE, (Map) loader.getProperties());
sources.addFirst(mps);
}
}

Servlet init and Class

I actually have a programm with a servlet :
#WebServlet("/Controler")
public class Controler extends HttpServlet {
}
I need to use a property file : file.properties in my program. To load it, I have a class :
public class PropLoader {
private final static String m_propertyFileName = "file.properties";
public static String getProperty(String a_key){
String l_value = "";
Properties l_properties = new Properties();
FileInputStream l_input;
try {
l_input = new FileInputStream(m_propertyFileName); // File not found exception
l_properties.load(l_input);
l_value = l_properties.getProperty(a_key);
l_input.close();
} catch (Exception e) {
e.printStackTrace();
}
return l_value;
}
}
My property file is in the WebContent folder, and I can access it with :
String path = getServletContext().getRealPath("/file.properties");
But I can't call theses methods in another class than the servlet...
How can I access to my property file in the PropLoader class ?
If you want to read the file from within the webapp structure, then you should use ServletContext.getResourceAsStream(). And of course, since you load it from the webapp, you need a reference to the object representing the webapp: ServletContext. You can get such a reference by overriding init() in your servlet, calling getServletConfig().getServletContext(), and pass the servlet context to the method loading the file:
#WebServlet("/Controler")
public class Controler extends HttpServlet {
private Properties properties;
#Override
public void init() {
properties = PropLoader.load(getServletConfig().getServletContext());
}
}
public class PropLoader {
private final static String FILE_PATH = "/file.properties";
public static Properties load(ServletContext context) {
Properties properties = new Properties();
properties.load(context.getResourceAsStream(FILE_PATH));
return properties;
}
}
Note that some exceptions must be handled.
Another solution would be to put the file under WEB-INF/classes in the deployed webapp, and use the ClassLoader to load the file: getClass().getResourceAsStream("/file.properties"). This way, you don't need a reference to ServletContext.
I would recommend to use the getResourceAsStream method (example below). It would need that the properties file be at the WAR classpath.
InputStream in = YourServlet.class.getClassLoader().getResourceAsStream(path_and_name);
Regards
Luan

Dynamically accessing properties using Spring 3.1's property abstraction

I'm trying to dynamically access properties from Spring's Environment property abstraction.
I declare my property files like this:
<context:property-placeholder
location="classpath:server.common.properties,
classpath:server.${my-environment}.properties" />
In my property file server.test.properties, I define the following:
myKey=foo
Then, given the following code:
#Component
public class PropertyTest {
#Value("${myKey}")
private String propertyValue;
#Autowired
private PropertyResolver propertyResolver;
public function test() {
String fromResolver = propertyResolver.getProperty("myKey");
}
}
When I run this code, I end up with propertyValue='foo', but fromResolver=null;
Receiving propertyValue indicates that the properties are being read, (and I know this from other parts of my code). However, attempting to look them up dynamically is failing.
Why? How can I dynamically look up property values, without having to use #Value?
Simply adding a <context:property-placeholder/> doesn't add a new PropertySource to the Environment. If you read the article you linked completely, you'll see it suggests registering an ApplicationContextInitializer in order to add new PropertySources so they'll be available in the way you're trying to use them.
To get this to work I had to split out the reading of the properties into a #Configuration bean, as shown here.
Here's the complete example:
#Configuration
#PropertySource("classpath:/server.${env}.properties")
public class AngularEnvironmentModuleConfiguration {
private static final String PROPERTY_LIST_NAME = "angular.environment.properties";
#Autowired
private Environment environment;
#Bean(name="angularEnvironmentProperties")
public Map<String,String> getAngularEnvironmentProperties()
{
String propertiesToInclude = environment.getProperty(PROPERTY_LIST_NAME, "");
String[] propertyNames = StringUtils.split(propertiesToInclude, ",");
Map<String,String> properties = Maps.newHashMap();
for (String propertyName : propertyNames)
{
String propertyValue = environment.getProperty(propertyName);
properties.put(propertyName, propertyValue);
}
return properties;
}
}
The set of properties are then injected elsewhere, to be consumed.

How to use config properties file throughout the classes?

I need my Java app to read the config properties from a file and use them throughout the classes. I'm thinking of a separate class, that would return a map of property_key:property_value for each of the properties in the file. Then I would read the values from this map in other classes.
Maybe there are other, more commonly used options?
My properties file is simple and has about 15 entries.
Just use java.util.Properties to load it. It implements Map already.
You can load and get hold of the properties statically. Here's an example assuming that you've a config.properties file in the com.example package:
public final class Config {
private static final Properties properties = new Properties();
static {
try {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
properties.load(loader.getResourceAsStream("com/example/config.properties"));
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
}
public static String getSetting(String key) {
return properties.getProperty(key);
}
// ...
}
Which can be used as
String foo = Config.getSetting("foo");
// ...
You could if necessary abstract this implementation away by an interface and get the instance by an abstract factory.

Categories

Resources