Results 1 to 19 of 19
  1. #1
    Pavlo is offline Member
    Join Date
    Dec 2012
    Posts
    28
    Rep Power
    0

    Default Config class - what is the best approach?

    Hello

    I work with java for a while and in few applications use settings class, that stores global application config. But I realise I alredy redo the same class with different approaches. All these works, but I not find any preferences of any of them.

    The first I create private fields with public getters and setter. This works because settings file instantiated once:

    Java Code:
    class Config{
    	private String name = "Best app";
    	private String address = "web";
    	
    	//getters
    	//...
    }
    But why not use static fields? This even not need the class to be instantiated. So I tried this also:

    Java Code:
    class Config{
    	private static String name = "Best app";
    	private static String address = "web";
    	
    	//getters
    	//...
    }
    Third - instead of fields for each property I can use HashTable so:

    Java Code:
    class Config{
    	private HashTable<String,String> settings;
    
    	public Config(){
    		settings.put("name","Best app");
    		settings.put("address","web");
    	}
    	
    	//getter for settings
    	//...
    }
    Four. Now I work on Spring app, and can do the same with Spring bean, so Spring container instantiate this Config class, and it will be accesible from all application.

    I not describe how I populate this settings data. It is quite obvious for me. But question, what is the best approach to create Config class with application global settings and why?
    Last edited by Pavlo; 04-10-2016 at 10:10 PM.

  2. #2
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    6,226
    Rep Power
    13

    Default Re: Config class - what is the best approach?

    I would say if you are going to have values for an app that can be configured, then I would put them in a resource file or equivalent. Then you can change the values without having to recompile the code.

    Regards,
    Jim
    The JavaTM Tutorials | SSCCE | Java Naming Conventions
    Poor planning on your part does not constitute an emergency on my part

  3. #3
    Pavlo is offline Member
    Join Date
    Dec 2012
    Posts
    28
    Rep Power
    0

    Default Re: Config class - what is the best approach?

    Hi. :)

    I use different file storage techniques for this, like xml, json or properties file. But I not see any sense to hit file every time I need some Config data field, so it should be populated with all settings data from file on first time settings requested (or at Config class construction time), but this is the other story :) . The question is how to place settings fields inside Config class?

  4. #4
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    14,422
    Blog Entries
    7
    Rep Power
    28

    Default Re: Config class - what is the best approach?

    Why not use a Properties object? A Properties object can be read from a file and written to a file; you only have to load a Properties file once ... (see the API docs).

    kind regards,

    Jos
    Build a wall around Donald Trump; I'll pay for it.

  5. #5
    Pavlo is offline Member
    Join Date
    Dec 2012
    Posts
    28
    Rep Power
    0

    Default Re: Config class - what is the best approach?

    Ok. I see my initial questions examples not clear :) . To keep things simple, here example of Java class, that stores application settings. It uses Properties class (and this is not an issue at all: what technique to use when read from disk). In this class properties are private instance fields. But is it not better to make fields static and not instantiate this class? The second option not create data fields, but instead use one data field with HashTable<String, String> type. It will store property - value entries.

    Hope now it should be clear :)

    Java Code:
    /**
     * This class loads settings from file once and stores them 
     * until application done its tasks.
     */ 
    public class Context {
    	private static final Logger LOGGER = Logger.getLogger(Context.class
    			.getName());
    
    	private static final String SETTINGS_FILE_NAME = "config.properties";
    	
    	private final static Context CONTEXT_INSTANCE = initialize();
    	
    	private String dbFromURL;
    	private String dbFromUser;
    	private String dbFromPassword;
    
    	private String dbToURL;
    	private String dbToUser;
    	private String dbToPassword;
    
    	private String loggerDateFormat;
    	
    	private Context() throws IOException{
    		this.loadFromFile();
    	}
    	
    	private static Context initialize(){
    		Context context = null;
    		try{
    			context = new Context();
    			return context;
    		}catch(Exception e){
    			LOGGER.log(Level.SEVERE, "Cannot get context ", e);
    		}
    		return null;
    	}
    	
    	public static Context getInstance(){
    		return CONTEXT_INSTANCE;
    	}
    	
    	public void loadFromFile() throws IOException{
    		LOGGER.log(Level.INFO,
    				"Read settings from: " + SETTINGS_FILE_NAME);
    		try(InputStream input = new FileInputStream(SETTINGS_FILE_NAME);) {
    			// load a properties file
    			Properties properties = new Properties();
    			properties.load(input);
    			dbFromURL = properties.getProperty("dbFromURL");
    			dbFromUser = properties.getProperty("dbFromUser");
    			dbFromPassword = properties
    					.getProperty("dbFromPassword");
    			dbToURL = properties.getProperty("dbToURL");
    			dbToUser = properties.getProperty("dbToUser");
    			dbToPassword = properties
    					.getProperty("dbToPassword");
    			loggerDateFormat = properties
    					.getProperty("loggerDateFormat");
    		}catch(IOException e){
    			LOGGER.log(Level.SEVERE, "Settings file read error.", e);
    			throw(e);
    		}
    	}
    
    	public String getDbFromURL() {
    		return dbFromURL;
    	}
    
    	public String getDbFromUser() {
    		return dbFromUser;
    	}
    
    	public String getDbFromPassword() {
    		return dbFromPassword;
    	}
    
    	public String getDbToURL() {
    		return dbToURL;
    	}
    
    	public String getDbToUser() {
    		return dbToUser;
    	}
    
    	public String getDbToPassword() {
    		return dbToPassword;
    	}
    
    	public String getLoggerDateFormat(){
    		return loggerDateFormat;
    	}
    	
    	public String getFormattedDate(Date date) throws IOException{
    		if (date!=null) {
    			return new SimpleDateFormat(loggerDateFormat).format(date);
    		}
    		return null; 
    	}
    }

  6. #6
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    14,422
    Blog Entries
    7
    Rep Power
    28

    Default Re: Config class - what is the best approach?

    Quote Originally Posted by Pavlo View Post
    Ok. I see my initial questions examples not clear :) . To keep things simple, here example of Java class, that stores application settings. It uses Properties class (and this is not an issue at all: what technique to use when read from disk). In this class properties are private instance fields. But is it not better to make fields static and not instantiate this class? The second option not create data fields, but instead use one data field with HashTable<String, String> type. It will store property - value entries.

    Hope now it should be clear :)
    No it isn't; why do you want to store the separate properties in (static) name fields? The Properties class (which is a HashTable which implements the Map interface) can do it all for you ...

    kind regards,

    Jos
    Build a wall around Donald Trump; I'll pay for it.

  7. #7
    SurfMan's Avatar
    SurfMan is offline Godlike
    Join Date
    Nov 2012
    Location
    The Netherlands
    Posts
    1,993
    Rep Power
    9

    Default Re: Config class - what is the best approach?

    To expand on Jos' answer: you could keep a reference to the Properties object in your class and in the getDB* methods, just dig in to the Properties object. No need for all those fields:
    Java Code:
    class Config {
       private static Properties props;
       static {
          init();
       }
    
       private static void init() {
          //load Properties here
       }
       
       public static String getDbFromURL() {
          return props.getProperty("dbFromURL");
       }
    ...
    }
    You could also have the key as public static final fields, and use that as parameter to get the value:
    Java Code:
    class Config {
       public static final String DB_FROM_URL="dbFromURL";
       ... more of these
    
       private static Properties props;
       static {
          init();
       }
    
       private static void init() {
          //load Properties here
       }
       
       public static String getValue(String key) {
          return props.getProperty(key);
       }
    
    }
    Then in your code: String dbFromURL = Config.getValue( Config.DB_FROM_URL);

    Or go wild with enums...
    "It's not fixed until you stop calling the problem weird and you understand what was wrong." - gimbal2 2013

  8. #8
    Pavlo is offline Member
    Join Date
    Dec 2012
    Posts
    28
    Rep Power
    0

    Default Re: Config class - what is the best approach?

    Yes, now I see idea:

    Properties class extends Hashtable, so I can use Properties class instance as static member in my Config class to store properties values. I not understand that before.

    SurfMan, from examples you give I like them both :) What is the better?
    Last edited by Pavlo; 04-11-2016 at 07:39 PM.

  9. #9
    SurfMan's Avatar
    SurfMan is offline Godlike
    Join Date
    Nov 2012
    Location
    The Netherlands
    Posts
    1,993
    Rep Power
    9

    Default Re: Config class - what is the best approach?

    Quote Originally Posted by Pavlo View Post
    Yes, now I see idea:

    Properties class extends Hashtable, so I can use Properties class instance as static member in my Config class to store properties values. I not understand that before.

    SurfMan, from examples you give I like them both :) What is the better?
    I only use the second, because I don't have to create new methods for each config option, only the final static String at the top.
    "It's not fixed until you stop calling the problem weird and you understand what was wrong." - gimbal2 2013

  10. #10
    Pavlo is offline Member
    Join Date
    Dec 2012
    Posts
    28
    Rep Power
    0

    Default Re: Config class - what is the best approach?

    Thanks a lot! Will take it in my new application :)

  11. #11
    SurfMan's Avatar
    SurfMan is offline Godlike
    Join Date
    Nov 2012
    Location
    The Netherlands
    Posts
    1,993
    Rep Power
    9

    Default Re: Config class - what is the best approach?

    Some more inspiration for your config class:
    - Make it possible to change values: setValue(String key, String value)
    - Make a save() method to store changed values
    - More generic methods to prevent your code from being full of Boolean.parseBoolean() and Integer.parseInt(), for example:
    public static boolean getBooleanValue(String key) {
    return Boolean.parseBoolean(props.getProperty(key));
    }

    Happy coding!
    "It's not fixed until you stop calling the problem weird and you understand what was wrong." - gimbal2 2013

  12. #12
    Pavlo is offline Member
    Join Date
    Dec 2012
    Posts
    28
    Rep Power
    0

    Default Re: Config class - what is the best approach?

    :) You are the best! Just today I redid Config class, though idea about getBooleanValue method is brilliant. Will redo calls with Integer and Boolean tomorrow. As about setValue() and save() methods, in my current app all settings come from file, and no other user input, though it is interesting for future work.

    Thanks once more!

  13. #13
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    13,541
    Rep Power
    26

    Default Re: Config class - what is the best approach?

    Since this is a Spring app why are you not binding directly from a Properties file?
    Java Code:
    @Service
    public ConfigService {
        @Value(${some.property.value})
        private String firstProperty
    
    ... getters etc.
    }
    Please do not ask for code as refusal often offends.

    ** This space for rent **

  14. #14
    Pavlo is offline Member
    Join Date
    Dec 2012
    Posts
    28
    Rep Power
    0

    Default Re: Config class - what is the best approach?

    Never heard about this feature before:
    Since this is a Spring app why are you not binding directly from a Properties file?
    And see it good too But already stick with Properties class (Hashtable) approach. Think is it worth to refactor. Looks like we come where I start.

    Next I have to update my application a bit, and it happens that I have to add a final property to Config class. The problem is: one of classes should have annotation attribute, linked to a property value from a properties file, and it should be constant. (actually it is @Table(name="my_table") and my_table value should be chosen from config file). Hashtable entity value is not final. So straight
    Java Code:
    Config.getValue("table_name")
    not works.

    I tried spring annotation with final field, but it not works too, because final value may have not been initialized

    Java Code:
    @Service
    public class ConfigService{
    	 @Value("${firstProperty}")
    	 private final String firstProperty;
    }
    One more tried: put in Config class static final variable and initialize it like:

    Java Code:
    private static final String stringAttribute = properties.getProperty("stringAttributeProperty");
    but not work either. Says: must be constant . Not get here why? String itself immutable, and variable marked as final.

    Is there any solution to fill annotation attribute so it will be immutable, but from Properties class instance?

  15. #15
    SurfMan's Avatar
    SurfMan is offline Godlike
    Join Date
    Nov 2012
    Location
    The Netherlands
    Posts
    1,993
    Rep Power
    9

    Default Re: Config class - what is the best approach?

    Values in annotations must follow certain rules. String values for example must be constants. See the discussion here: http://www.java-forums.org/new-java/...nnotation.html
    "It's not fixed until you stop calling the problem weird and you understand what was wrong." - gimbal2 2013

  16. #16
    Pavlo is offline Member
    Join Date
    Dec 2012
    Posts
    28
    Rep Power
    0

    Default Re: Config class - what is the best approach?

    Looks like it is just impossible to fill the annotation attribute from Config class because 9.7 from your post link Chapter*9.*Interfaces states:
    An annotation is a marker which associates information with a program construct, but has no effect at run time.
    So I will try to find some other solution with Spring.

    Thanks.

  17. #17
    SurfMan's Avatar
    SurfMan is offline Godlike
    Join Date
    Nov 2012
    Location
    The Netherlands
    Posts
    1,993
    Rep Power
    9

    Default Re: Config class - what is the best approach?

    Quote Originally Posted by Pavlo View Post
    Looks like it is just impossible to fill the annotation attribute from Config class because 9.7 from your post link Chapter*9.*Interfaces states:

    So I will try to find some other solution with Spring.

    Thanks.
    You can *read* the annotation at run-time, but that's where it ends. No writing/modifying.
    "It's not fixed until you stop calling the problem weird and you understand what was wrong." - gimbal2 2013

  18. #18
    SurfMan's Avatar
    SurfMan is offline Godlike
    Join Date
    Nov 2012
    Location
    The Netherlands
    Posts
    1,993
    Rep Power
    9

    Default Re: Config class - what is the best approach?

    Update: maybe this article will help. It looks like they pull it off.

    How to set development/test/production environment in spring project (Java Config) | Code Breeze !
    "It's not fixed until you stop calling the problem weird and you understand what was wrong." - gimbal2 2013

  19. #19
    Pavlo is offline Member
    Join Date
    Dec 2012
    Posts
    28
    Rep Power
    0

    Default Re: Config class - what is the best approach?

    Actually I use Spring Boot, and there included Hibernate. Unfortunately Spring team decide that developers will not be interested in traditional xml file, with hibernate object - table mapping. So one of solutions described here 73.*Data Access. But this is the different topic...

    Thanks a lot!

Similar Threads

  1. config.ini file?
    By JavaJimme in forum JDBC
    Replies: 2
    Last Post: 05-09-2013, 05:47 PM
  2. Issues With Config??
    By Spindraft in forum New To Java
    Replies: 11
    Last Post: 11-02-2012, 04:05 AM
  3. How to approach this problem?
    By Zigster in forum New To Java
    Replies: 16
    Last Post: 04-27-2012, 06:53 PM
  4. tools4j-config
    By java software in forum Java Software
    Replies: 0
    Last Post: 02-05-2012, 06:56 PM
  5. struts-config.xml
    By Heather in forum Web Frameworks
    Replies: 2
    Last Post: 01-17-2008, 12:23 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •