Properties and Configuration β Properties, ResourceBundle, Config Files, and Preferences API
In this tutorial, you will learn about Properties and Configuration. We cover key concepts, practical examples, and best practices to help you master this topic.
Java Properties and ResourceBundle classes manage configuration data and internationalized messages through key-value pairs. Every non-trivial application needs configuration β database URLs, API keys, feature flags, and user preferences. Java provides several mechanisms for managing this data.
What You'll Learn
- Properties class: loading, storing, and manipulating key-value pairs
- ResourceBundle: locale-specific message bundles
- Configuration file conventions (.properties, .xml)
- Preferences API: platform-specific user/application preferences
Why It Matters
Hard-coding configuration values is a maintenance nightmare. Externalizing configuration lets you change behavior without recompiling, support multiple environments (dev, test, prod), and internationalize your application.
Real-World Use
Spring Boot's application.properties, log4j's log4j.properties, and database connection parameters are all managed through properties files. Internationalized UIs use ResourceBundle.
The Properties Class
Properties extends Hashtable<Object, Object> and stores key-value pairs as strings:
Properties config = new Properties();
config.setProperty("db.url", "jdbc:mysql://localhost:3306/mydb");
config.setProperty("db.user", "root");
config.setProperty("db.password", "secret");
// Save to file
try (OutputStream out = new FileOutputStream("config.properties")) {
config.store(out, "Database Configuration");
}
Loading Properties
Properties config = new Properties();
// From file
try (InputStream in = new FileInputStream("config.properties")) {
config.load(in);
}
// From classpath
try (InputStream in = getClass().getClassLoader()
.getResourceAsStream("config.properties")) {
config.load(in);
}
String url = config.getProperty("db.url");
String user = config.getProperty("db.user");
String password = config.getProperty("db.password", "default"); // with default
XML Format
// Save as XML
config.storeToXML(new FileOutputStream("config.xml"), "Config");
// Load from XML
config.loadFromXML(new FileInputStream("config.xml"));
ResourceBundle for Internationalization
ResourceBundle manages locale-specific messages:
Properties Files
Create messages.properties (default) and locale-specific variants:
# messages.properties (default)
greeting=Hello
farewell=Goodbye
# messages_de.properties (German)
greeting=Hallo
farewell=TschΓΌss
# messages_fr.properties (French)
greeting=Bonjour
farewell=Au revoir
Loading ResourceBundle
// Default locale
ResourceBundle bundle = ResourceBundle.getBundle("messages");
System.out.println(bundle.getString("greeting")); // Hello
// German locale
ResourceBundle deBundle = ResourceBundle.getBundle("messages", Locale.GERMAN);
System.out.println(deBundle.getString("greeting")); // Hallo
// French locale
ResourceBundle frBundle = ResourceBundle.getBundle("messages", Locale.FRENCH);
System.out.println(frBundle.getString("greeting")); // Bonjour
// Custom locale
Locale esLocale = new Locale("es", "ES");
ResourceBundle esBundle = ResourceBundle.getBundle("messages", esLocale);
Fallback Resolution
ResourceBundle searches in this order:
- Requested locale (e.g.,
messages_fr_FR) - Language (e.g.,
messages_fr) - Default locale (e.g.,
messages_en_US) - Base bundle (
messages.properties)
Preferences API
The Preferences API provides a platform-independent way to store user and system preferences:
// User preferences (per user)
Preferences prefs = Preferences.userNodeForPackage(MyApp.class);
prefs.put("windowWidth", "1024");
prefs.put("windowHeight", "768");
prefs.putBoolean("showToolbar", true);
prefs.putInt("recentFiles", 5);
// System preferences (shared across users)
Preferences systemPrefs = Preferences.systemNodeForPackage(MyApp.class);
systemPrefs.put("installPath", "/opt/myapp");
// Read preferences
String width = prefs.get("windowWidth", "800"); // default 800
boolean showToolbar = prefs.getBoolean("showToolbar", true);
int recentFiles = prefs.getInt("recentFiles", 3);
Where Preferences Are Stored
- Windows: Registry (
HKEY_CURRENT_USER\Software\JavaSoft\Prefs) - macOS/Linux:
~/.java/.userPrefs
Configuration Best Practices
- Externalize all environment-specific values. URLs, credentials, and feature flags should be in configuration files, not code.
- Use a default configuration. Provide sensible defaults that work out of the box.
- Keep secrets out of version control. Use environment variables or a secrets manager for passwords and API keys.
- Validate configuration at startup. Fail Fast with clear error messages if required properties are missing.
- Consider YAML for complex config. The
.propertiesformat is flat; YAML supports nested structures. Use Spring Boot or a library like SnakeYAML.
Common Mistakes
- Hard-coding locale-specific strings. Internationalization is painful to retrofit. Use ResourceBundle from the start.
- Not providing defaults for getProperty(). Without defaults, missing properties return null, leading to
NullPointerException. - Forgetting that Properties extends Hashtable. You can get any type with
get("key"), but type safety is lost. UsegetProperty()for strings. - Storing mutable state in properties files. Properties files should be configuration, not a database. For frequent changes, use a database.
- Loading properties files with wrong encoding. Properties files are ISO 8859-1 by default. For Unicode, use
\uXXXXescapes or XML format.
Practice Questions
1. What is the difference between Properties and ResourceBundle?
Properties is a general key-value store for configuration. ResourceBundle is specifically designed for locale-sensitive messages with fallback resolution.
2. How does ResourceBundle resolve the correct locale file?
It searches: baseName_lang_country, baseName_lang, baseName_defaultLocale, baseName. For example: messages_fr_FR, messages_fr, messages_en, messages.
3. Where does the Preferences API store data?
Platform-dependent. On Windows: Registry. On macOS/Linux: ~/.java/.userPrefs directory.
4. What encoding do .properties files use by default?
ISO 8859-1 (Latin-1). Non-Latin-1 characters must be escaped with \uXXXX.
5. How do you specify a default value in Properties.getProperty()?
getProperty("key", "defaultValue"). Returns "defaultValue" if the key is not found.
Challenge Question:
Create a configuration framework that supports layered configuration β values from command-line arguments override environment variables, which override properties files, which override defaults. Use Properties for file-based config, system properties for environment overrides, and Map for defaults.
FAQ
{{< faq "How do I internationalize an application?" "1. Use ResourceBundle.getBundle() for all user-facing strings. 2. Create locale-specific properties files. 3. Use Locale.setDefault() or detect the user's locale. 4. Use MessageFormat for parameterized messages: bundle.getString(\"welcome\") with {0} placeholders." >}}
{{< faq "What is the @Value annotation in Spring?" "Spring's @Value(\"${property.name:default}\") injects configuration values from properties files. It is a more convenient way to access properties in Spring applications." >}}
Mini Project
Write a program ConfigurationDemo.java that:
- Creates an
AppConfigclass that loads configuration from a properties file - Reads database URL, username, and timeout with defaults
- Supports environment variable overrides (e.g.,
DB_URLoverridesdb.url) - Creates a ResourceBundle for internationalized welcome messages (English and Spanish)
- Uses the Preferences API to store and retrieve user preferences (theme, font size, window position)
- Saves the configuration as XML using
storeToXML() - Validates that required properties are present at startup and prints clear error messages
What's Next
Configuration is essential for deployment. But to build and distribute Java applications, you need build tools. Lesson 45 introduces Maven β the standard build tool for Java, covering pom.xml, the build lifecycle, dependencies, plugins, and multi-module projects.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro