GithubHelp home page GithubHelp logo

lightbend / config Goto Github PK

View Code? Open in Web Editor NEW
6.1K 197.0 965.0 4.54 MB

configuration library for JVM languages using HOCON files

Home Page: https://lightbend.github.io/config/

Scala 37.64% Java 61.93% HTML 0.43%
supported hocon configuration-library

config's Introduction

Configuration library for JVM languages.

Maven Central Build Status

Overview

  • implemented in plain Java with no dependencies
  • supports files in three formats: Java properties, JSON, and a human-friendly JSON superset
  • merges multiple files across all formats
  • can load from files, URLs, or classpath
  • good support for "nesting" (treat any subtree of the config the same as the whole config)
  • users can override the config with Java system properties, java -Dmyapp.foo.bar=10
  • supports configuring an app, with its framework and libraries, all from a single file such as application.conf
  • parses duration and size settings, "512k" or "10 seconds"
  • converts types, so if you ask for a boolean and the value is the string "yes", or you ask for a float and the value is an int, it will figure it out.
  • JSON superset features:
    • comments
    • includes
    • substitutions ("foo" : ${bar}, "foo" : Hello ${who})
    • properties-like notation (a.b=c)
    • less noisy, more lenient syntax
    • substitute environment variables (logdir=${HOME}/logs)
  • API based on immutable Config instances, for thread safety and easy reasoning about config transformations
  • extensive test coverage

This library limits itself to config files. If you want to load config from a database or something, you would need to write some custom code. The library has nice support for merging configurations so if you build one from a custom source it's easy to merge it in.

Table of Contents generated with DocToc

Essential Information

Binary Releases

Typesafe Config is compatible with Java 8 and above.

You can find published releases on Maven Central.

<dependency>
    <groupId>com.typesafe</groupId>
    <artifactId>config</artifactId>
    <version>1.4.3</version>
</dependency>

sbt dependency:

libraryDependencies += "com.typesafe" % "config" % "1.4.3"

Link for direct download if you don't use a dependency manager:

Release Notes

Please see NEWS.md in this directory, https://github.com/lightbend/config/blob/main/NEWS.md

API docs

Bugs and Patches

NOTE: Please read Readme #Maintained-by before spending time suggesting changes to this library.

Report bugs to the GitHub issue tracker. Send patches as pull requests on GitHub.

Before we can accept pull requests, you will need to agree to the Typesafe Contributor License Agreement online, using your GitHub account - it takes 30 seconds. You can do this at https://www.lightbend.com/contribute/cla

Please see CONTRIBUTING for more including how to make a release.

Build

The build uses sbt and the tests are written in Scala; however, the library itself is plain Java and the published jar has no Scala dependency.

Using the Library

API Example

import com.typesafe.config.ConfigFactory

Config conf = ConfigFactory.load();
int bar1 = conf.getInt("foo.bar");
Config foo = conf.getConfig("foo");
int bar2 = foo.getInt("bar");

Longer Examples

See the examples in the examples/ directory.

You can run these from the sbt console with the commands project config-simple-app-java and then run.

In brief, as shown in the examples:

  • libraries should use a Config instance provided by the app, if any, and use ConfigFactory.load() if no special Config is provided. Libraries should put their defaults in a reference.conf on the classpath.
  • apps can create a Config however they want (ConfigFactory.load() is easiest and least-surprising), then provide it to their libraries. A Config can be created with the parser methods in ConfigFactory or built up from any file format or data source you like with the methods in ConfigValueFactory.

Immutability

Objects are immutable, so methods on Config which transform the configuration return a new Config. Other types such as ConfigParseOptions, ConfigResolveOptions, ConfigObject, etc. are also immutable. See the API docs for details of course.

Schemas and Validation

There isn't a schema language or anything like that. However, two suggested tools are:

  • use the checkValid() method
  • access your config through a Settings class with a field for each setting, and instantiate it on startup (immediately throwing an exception if any settings are missing)

In Scala, a Settings class might look like:

class Settings(config: Config) {

    // validate vs. reference.conf
    config.checkValid(ConfigFactory.defaultReference(), "simple-lib")

    // non-lazy fields, we want all exceptions at construct time
    val foo = config.getString("simple-lib.foo")
    val bar = config.getInt("simple-lib.bar")
}

See the examples/ directory for a full compilable program using this pattern.

Standard behavior

The convenience method ConfigFactory.load() loads the following (first-listed are higher priority):

  • system properties
  • application.conf (all resources on classpath with this name)
  • application.json (all resources on classpath with this name)
  • application.properties (all resources on classpath with this name)
  • reference.conf (all resources on classpath with this name)

The idea is that libraries and frameworks should ship with a reference.conf in their jar. Applications should provide an application.conf, or if they want to create multiple configurations in a single JVM, they could use ConfigFactory.load("myapp") to load their own myapp.conf.

Libraries and frameworks should default to ConfigFactory.load() if the application does not provide a custom Config object. This way, libraries will see configuration from application.conf and users can configure the whole app, with its libraries, in a single application.conf file.

Libraries and frameworks should also allow the application to provide a custom Config object to be used instead of the default, in case the application needs multiple configurations in one JVM or wants to load extra config files from somewhere. The library examples in examples/ show how to accept a custom config while defaulting to ConfigFactory.load().

For applications using application.{conf,json,properties}, system properties can be used to force a different config source (e.g. from command line -Dconfig.file=path/to/config-file):

  • config.resource specifies a resource name - not a basename, i.e. application.conf not application
  • config.file specifies a filesystem path, again it should include the extension, not be a basename
  • config.url specifies a URL

Note: you need to pass -Dconfig.file=path/to/config-file before the jar itself, e.g. java -Dconfig.file=path/to/config-file.conf -jar path/to/jar-file.jar. Same applies for -Dconfig.resource=config-file.conf

These system properties specify a replacement for application.{conf,json,properties}, not an addition. They only affect apps using the default ConfigFactory.load() configuration. In the replacement config file, you can use include "application" to include the original default config file; after the include statement you could go on to override certain settings.

If you set config.resource, config.file, or config.url on-the-fly from inside your program (for example with System.setProperty()), be aware that ConfigFactory has some internal caches and may not see new values for system properties. Use ConfigFactory.invalidateCaches() to force-reload system properties.

Note about resolving substitutions in reference.conf and application.conf

The substitution syntax ${foo.bar} will be resolved twice. First, all the reference.conf files are merged and then the result gets resolved. Second, all the application.conf are layered over the unresolved reference.conf and the result of that gets resolved again.

The implication of this is that the reference.conf stack has to be self-contained; you can't leave an undefined value ${foo.bar} to be provided by application.conf. It is however possible to override a variable that reference.conf refers to, as long as reference.conf also defines that variable itself.

Merging config trees

Any two Config objects can be merged with an associative operation called withFallback, like merged = firstConfig.withFallback(secondConfig).

The withFallback operation is used inside the library to merge duplicate keys in the same file and to merge multiple files. ConfigFactory.load() uses it to stack system properties over application.conf over reference.conf.

You can also use withFallback to merge in some hardcoded values, or to "lift" a subtree up to the root of the configuration; say you have something like:

foo=42
dev.foo=57
prod.foo=10

Then you could code something like:

Config devConfig = originalConfig
                     .getConfig("dev")
                     .withFallback(originalConfig)

There are lots of ways to use withFallback.

How to handle defaults

Many other configuration APIs allow you to provide a default to the getter methods, like this:

boolean getBoolean(String path, boolean fallback)

Here, if the path has no setting, the fallback would be returned. An API could also return null for unset values, so you would check for null:

// returns null on unset, check for null and fall back
Boolean getBoolean(String path)

The methods on the Config interface do NOT do this, for two major reasons:

  1. If you use a config setting in two places, the default fallback value gets cut-and-pasted and typically out of sync. This can result in Very Evil Bugs.
  2. If the getter returns null (or None, in Scala) then every time you get a setting you have to write handling code for null/None and that code will almost always just throw an exception. Perhaps more commonly, people forget to check for null at all, so missing settings result in NullPointerException.

For most situations, failure to have a setting is simply a bug to fix (in either code or the deployment environment). Therefore, if a setting is unset, by default the getters on the Config interface throw an exception.

If you want to allow a setting to be missing from application.conf in a particular case, then here are some options:

  1. Set it in a reference.conf included in your library or application jar, so there's a default value.
  2. Use the Config.hasPath() method to check in advance whether the path exists (rather than checking for null/None after as you might in other APIs).
  3. Catch and handle ConfigException.Missing. NOTE: using an exception for control flow like this is much slower than using Config.hasPath(); the JVM has to do a lot of work to throw an exception.
  4. In your initialization code, generate a Config with your defaults in it (using something like ConfigFactory.parseMap()) then fold that default config into your loaded config using withFallback(), and use the combined config in your program. "Inlining" your reference config in the code like this is probably less convenient than using a reference.conf file, but there may be reasons to do it.
  5. Use Config.root() to get the ConfigObject for the Config; ConfigObject implements java.util.Map<String,?> and the get() method on Map returns null for missing keys. See the API docs for more detail on Config vs. ConfigObject.
  6. Set the setting to null in reference.conf, then use Config.getIsNull and Config.hasPathOrNull to handle null in a special way while still throwing an exception if the setting is entirely absent.

The recommended path (for most cases, in most apps) is that you require all settings to be present in either reference.conf or application.conf and allow ConfigException.Missing to be thrown if they are not. That's the design intent of the Config API design.

Consider the "Settings class" pattern with checkValid() to verify that you have all settings when you initialize the app. See the Schemas and Validation section of this README for more details on this pattern.

If you do need a setting to be optional: checking hasPath() in advance should be the same amount of code (in Java) as checking for null afterward, without the risk of NullPointerException when you forget. In Scala, you could write an enrichment class like this to use the idiomatic Option syntax:

implicit class RichConfig(val underlying: Config) extends AnyVal {
  def getOptionalBoolean(path: String): Option[Boolean] = if (underlying.hasPath(path)) {
     Some(underlying.getBoolean(path))
  } else {
     None
  }
}

Since this library is a Java library it doesn't come with that out of the box, of course.

It is understood that sometimes defaults in code make sense. For example, if your configuration lets users invent new sections, you may not have all paths up front and may be unable to set up defaults in reference.conf for dynamic paths. The design intent of Config isn't to prohibit inline defaults, but simply to recognize that it seems to be the 10% case (rather than the 90% case). Even in cases where dynamic defaults are needed, you may find that using withFallback() to build a complete nothing-missing Config in one central place in your code keeps things tidy.

Whatever you do, please remember not to cut-and-paste default values into multiple places in your code. You have been warned! :-)

Understanding Config and ConfigObject

To read and modify configuration, you'll use the Config interface. A Config looks at a JSON-equivalent data structure as a one-level map from paths to values. So if your JSON looks like this:

  "foo" : {
    "bar" : 42
    "baz" : 43
  }

Using the Config interface, you could write conf.getInt("foo.bar"). The foo.bar string is called a path expression (HOCON.md has the syntax details for these expressions). Iterating over this Config, you would get two entries; "foo.bar" : 42 and "foo.baz" : 43. When iterating a Config you will not find nested Config (because everything gets flattened into one level).

When looking at a JSON tree as a Config, null values are treated as if they were missing. Iterating over a Config will skip null values.

You can also look at a Config in the way most JSON APIs would, through the ConfigObject interface. This interface represents an object node in the JSON tree. ConfigObject instances come in multi-level trees, and the keys do not have any syntax (they are just strings, not path expressions). Iterating over the above example as a ConfigObject, you would get one entry "foo" : { "bar" : 42, "baz" : 43 }, where the value at "foo" is another nested ConfigObject.

In ConfigObject, null values are visible (distinct from missing values), just as they are in JSON.

ConfigObject is a subtype of ConfigValue, where the other subtypes are the other JSON types (list, string, number, boolean, null).

Config and ConfigObject are two ways to look at the same internal data structure, and you can convert between them for free using Config.root() and ConfigObject.toConfig().

ConfigBeanFactory

As of version 1.3.0, if you have a Java object that follows JavaBean conventions (zero-args constructor, getters and setters), you can automatically initialize it from a Config.

Use ConfigBeanFactory.create(config.getConfig("subtree-that-matches-bean"), MyBean.class) to do this.

Creating a bean from a Config automatically validates that the config matches the bean's implied schema. Bean fields can be primitive types, typed lists such as List<Integer>, java.time.Duration, ConfigMemorySize, or even a raw Config, ConfigObject, or ConfigValue (if you'd like to deal with a particular value manually).

Using HOCON, the JSON Superset

The JSON superset is called "Human-Optimized Config Object Notation" or HOCON, and files use the suffix .conf. See HOCON.md in this directory for more detail.

After processing a .conf file, the result is always just a JSON tree that you could have written (less conveniently) in JSON.

Features of HOCON

  • Comments, with # or //
  • Allow omitting the {} around a root object
  • Allow = as a synonym for :
  • Allow omitting the = or : before a { so foo { a : 42 }
  • Allow omitting commas as long as there's a newline
  • Allow trailing commas after last element in objects and arrays
  • Allow unquoted strings for keys and values
  • Unquoted keys can use dot-notation for nested objects, foo.bar=42 means foo { bar : 42 }
  • Duplicate keys are allowed; later values override earlier, except for object-valued keys where the two objects are merged recursively
  • include feature merges root object in another file into current object, so foo { include "bar.json" } merges keys in bar.json into the object foo
  • include with no file extension includes any of .conf, .json, .properties
  • you can include files, URLs, or classpath resources; use include url("http://example.com") or file() or classpath() syntax to force the type, or use just include "whatever" to have the library do what you probably mean (Note: url()/file()/classpath() syntax is not supported in Play/Akka 2.0, only in later releases.)
  • substitutions foo : ${a.b} sets key foo to the same value as the b field in the a object
  • substitutions concatenate into unquoted strings, foo : the quick ${colors.fox} jumped
  • substitutions fall back to environment variables if they don't resolve in the config itself, so ${HOME} would work as you expect. Also, most configs have system properties merged in so you could use ${user.home}.
  • substitutions normally cause an error if unresolved, but there is a syntax ${?a.b} to permit them to be missing.
  • += syntax to append elements to arrays, path += "/bin"
  • multi-line strings with triple quotes as in Python or Scala

Examples of HOCON

All of these are valid HOCON.

Start with valid JSON:

{
    "foo" : {
        "bar" : 10,
        "baz" : 12
    }
}

Drop root braces:

"foo" : {
    "bar" : 10,
    "baz" : 12
}

Drop quotes:

foo : {
    bar : 10,
    baz : 12
}

Use = and omit it before {:

foo {
    bar = 10,
    baz = 12
}

Remove commas:

foo {
    bar = 10
    baz = 12
}

Use dotted notation for unquoted keys:

foo.bar=10
foo.baz=12

Put the dotted-notation fields on a single line:

foo.bar=10, foo.baz=12

The syntax is well-defined (including handling of whitespace and escaping). But it handles many reasonable ways you might want to format the file.

Note that while you can write HOCON that looks a lot like a Java properties file (and many properties files will parse as HOCON), the details of escaping, whitespace handling, comments, and so forth are more like JSON. The spec (see HOCON.md in this directory) has some more detailed notes on this topic.

Uses of Substitutions

The ${foo.bar} substitution feature lets you avoid cut-and-paste in some nice ways.

Factor out common values

This is the obvious use,

standard-timeout = 10ms
foo.timeout = ${standard-timeout}
bar.timeout = ${standard-timeout}

Inheritance

If you duplicate a field with an object value, then the objects are merged with last-one-wins. So:

foo = { a : 42, c : 5 }
foo = { b : 43, c : 6 }

means the same as:

foo = { a : 42, b : 43, c : 6 }

You can take advantage of this for "inheritance":

data-center-generic = { cluster-size = 6 }
data-center-east = ${data-center-generic}
data-center-east = { name = "east" }
data-center-west = ${data-center-generic}
data-center-west = { name = "west", cluster-size = 8 }

Using include statements you could split this across multiple files, too.

If you put two objects next to each other (close brace of the first on the same line with open brace of the second), they are merged, so a shorter way to write the above "inheritance" example would be:

data-center-generic = { cluster-size = 6 }
data-center-east = ${data-center-generic} { name = "east" }
data-center-west = ${data-center-generic} { name = "west", cluster-size = 8 }

Optional system or env variable overrides

In default uses of the library, exact-match system properties already override the corresponding config properties. However, you can add your own overrides, or allow environment variables to override, using the ${?foo} substitution syntax.

basedir = "/whatever/whatever"
basedir = ${?FORCED_BASEDIR}

Here, the override field basedir = ${?FORCED_BASEDIR} simply vanishes if there's no value for FORCED_BASEDIR, but if you set an environment variable FORCED_BASEDIR for example, it would be used.

A natural extension of this idea is to support several different environment variable names or system property names, if you aren't sure which one will exist in the target environment.

Object fields and array elements with a ${?foo} substitution value just disappear if the substitution is not found:

// this array could have one or two elements
path = [ "a", ${?OPTIONAL_A} ]

By setting the JVM property -Dconfig.override_with_env_vars=true it is possible to override any configuration value using environment variables even if an explicit substitution is not specified.

The environment variable value will override any pre-existing value and also any value provided as Java property.

With this option enabled only environment variables starting with CONFIG_FORCE_ are considered, and the name is mangled as follows:

  • the prefix CONFIG_FORCE_ is stripped
  • single underscore(_) is converted into a dot(.)
  • double underscore(__) is converted into a dash(-)
  • triple underscore(___) is converted into a single underscore(_)

i.e. The environment variable CONFIG_FORCE_a_b__c___d set the configuration key a.b-c_d

Set array values outside configuration files

Setting the value of array items from java properties or environment variables require specifying the index in the array for the value. So, while in HOCON you can set multiple values into an array or append to an array:

## HOCON
items = ["a", "b"]
items += "c"

Using java properties you specify the exact position:

-Ditems.0="a" -Ditems.1="b"

as well as with environment variables:

export CONFIG_FORCE_items_0=a
export CONFIG_FORCE_items_1=b

Concatenation

Values on the same line are concatenated (for strings and arrays) or merged (for objects).

This is why unquoted strings work, here the number 42 and the string foo are concatenated into a string 42 foo:

key : 42 foo

When concatenating values into a string, leading and trailing whitespace is stripped but whitespace between values is kept.

Quoted or unquoted strings can also concatenate with substitutions of course:

tasks-url : ${base-url}/tasks
tasks-url : ${base-url}"tasks:colon-must-be-quoted"

Note: the ${} syntax must be outside the quotes!

A concatenation can refer to earlier values of the same field:

path : "/bin"
path : ${path}":/usr/bin"

Arrays can be concatenated as well:

path : [ "/bin" ]
path : ${path} [ "/usr/bin" ]

There is a shorthand for appending to arrays:

// equivalent to: path = ${?path} [ "/usr/bin" ]
path += "/usr/bin"

To prepend or insert into an array, there is no shorthand.

When objects are "concatenated," they are merged, so object concatenation is just a shorthand for defining the same object twice. The long way (mentioned earlier) is:

data-center-generic = { cluster-size = 6 }
data-center-east = ${data-center-generic}
data-center-east = { name = "east" }

The concatenation-style shortcut is:

data-center-generic = { cluster-size = 6 }
data-center-east = ${data-center-generic} { name = "east" }

When concatenating objects and arrays, newlines are allowed inside each object or array, but not between them.

Non-newline whitespace is never a field or element separator. So [ 1 2 3 4 ] is an array with one unquoted string element "1 2 3 4". To get an array of four numbers you need either commas or newlines separating the numbers.

See the spec for full details on concatenation.

Note: Play/Akka 2.0 have an earlier version that supports string concatenation, but not object/array concatenation. += does not work in Play/Akka 2.0 either. Post-2.0 versions support these features.

Miscellaneous Notes

Debugging Your Configuration

If you have trouble with your configuration, some useful tips.

  • Set the Java system property -Dconfig.trace=loads to get output on stderr describing each file that is loaded. Note: this feature is not included in the older version in Play/Akka 2.0.
  • Use myConfig.root().render() to get a Config as a string with comments showing where each value came from. This string can be printed out on console or logged to a file etc.
  • If you see errors like com.typesafe.config.ConfigException$Missing: No configuration setting found for key foo, and you're sure that key is defined in your config file, they might appear e.g. when you're loading configuration from a thread that's not the JVM's main thread. Try passing the ClassLoader in manually - e.g. with ConfigFactory.load(getClass().getClassLoader()) or setting the context class loader. If you don't pass one, Lightbend Config uses the calling thread's contextClassLoader, and in some cases, it may not have your configuration files in its classpath, so loading the config on that thread can yield unexpected, erroneous results.

Supports Java 8 and Later

Currently the library is maintained against Java 8, but version 1.2.1 and earlier will work with Java 6.

Please use 1.2.1 if you need Java 6 support, though some people have expressed interest in a branch off of 1.3.x supporting Java 7. If you want to work on that branch you might bring it up on chat. We can release a jar for Java 7 if someone(s) steps up to maintain the branch. The main branch does not use Java 8 "gratuitously" but some APIs that use Java 8 types will need to be removed.

Rationale for Supported File Formats

(For the curious.)

The three file formats each have advantages.

  • Java .properties:
    • Java standard, built in to JVM
    • Supported by many tools such as IDEs
  • JSON:
    • easy to generate programmatically
    • well-defined and standard
    • bad for human maintenance, with no way to write comments, and no mechanisms to avoid duplication of similar config sections
  • HOCON/.conf:
    • nice for humans to read, type, and maintain, with more lenient syntax
    • built-in tools to avoid cut-and-paste
    • ways to refer to the system environment, such as system properties and environment variables

The idea would be to use JSON if you're writing a script to spit out config, and use HOCON if you're maintaining config by hand. If you're doing both, then mix the two.

Two alternatives to HOCON syntax could be:

  • YAML is also a JSON superset and has a mechanism for adding custom types, so the include statements in HOCON could become a custom type tag like !include, and substitutions in HOCON could become a custom tag such as !subst, for example. The result is somewhat clunky to write, but would have the same in-memory representation as the HOCON approach.
  • Put a syntax inside JSON strings, so you might write something like "$include" : "filename" or allow "foo" : "${bar}". This is a way to tunnel new syntax through a JSON parser, but other than the implementation benefit (using a standard JSON parser), it doesn't really work. It's a bad syntax for human maintenance, and it's not valid JSON anymore because properly interpreting it requires treating some valid JSON strings as something other than plain strings. A better approach is to allow mixing true JSON files into the config but also support a nicer format.

Other APIs (Wrappers, Ports and Utilities)

This may not be comprehensive - if you'd like to add mention of your wrapper, just send a pull request for this README. We would love to know what you're doing with this library or with the HOCON format.

Guice integration

Java (yep!) wrappers for the Java library

Scala wrappers for the Java library

Clojure wrappers for the Java library

Kotlin wrappers for the Java library

Scala port

Ruby port

Puppet module

Python port

C++ port

JavaScript port

C# port

Rust port

Go port

Erlang port

Linting tool

Online playground

Maintenance notes

License

The license is Apache 2.0, see LICENSE-2.0.txt.

Maintained by

The "Typesafe Config" library is an important foundation to how Akka and other JVM libraries manage configuration. We at Lightbend consider the functionality of this library as feature complete. We will make sure "Typesafe Config" keeps up with future JVM versions, but will rarely make any other changes.

We are thankful for all the work @havocp has put into creating the library initially and supporting its users over many more years, even after leaving Lightbend.

config's People

Contributors

2m avatar acaly avatar alexwei avatar andreatp avatar av-elier avatar bbaldino avatar benmccann avatar bugthesystem avatar chris-martin avatar dwijnand avatar ekrich avatar ennru avatar havocp avatar iamtodor avatar johnlon avatar jroper avatar ktoso avatar kxbmap avatar marcospereira avatar mslilah avatar nrktkt avatar ntviet18 avatar patriknw avatar pshirshov avatar psliwa avatar raboof avatar tea-dragon avatar tzarouali avatar vaigarashi avatar viktorklang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

config's Issues

Let ConfigFactory load from file or URL, not just resource

I have my settings defined outside of the broad application.conf settings.

val myConfig = System.getProperty("my.config")
val config = ConfigFactory.load(myConfig)

But I can only load these files if they're defined in the classpath. I want the option to load a configuration using loadFile or loadURL. I can't do it from the command line either, as config.url and config.file only work with application.conf.

Can it be compiled for Java 5 please

Currently have to recompile my own version; unless there are any J2SE 6 specific features (pretty rare) it would be good if the lib shipped at 1.5 as standard.

would an “override” modifier make sense?

I have seen it multiple times on the akka mailing list that a “bug” was ultimately due to getting the nesting of a setting wrong. Since .config is schemaless for good reasons, there is a priori not much we can do about it, but what about an override signal?

akka {
  debug {
    receive := on
  }
}

This should fail at merge time, telling the user that the setting does not actually override anything (which akka.actor.debug.receive would, from reference.conf). This would allow users to still put whatever they want into the config, while asserting that some of the settings are actually understood by the library which uses them.

replace the content of a config path

Currently, there is no easy way to get a new Config or ConfigObject with the content on a certain branch replaced (with fallback to original, of course).

a {
   b {
      c = 10 
      d = 7
   }
}
b1 {
   c = 11
}

I want to get a config that looks like

a {
   b {
      c = 11 
      d = 7
   }
}

(notice the fallback mechanism)

The only way (I found) to do this now is:

ConfigFactory.parseMap(Map("a" -> Map("b" -> config.getObject("b1").unwrapped)).asJava).withFallback(config)

I think this is a common need so it would be nice to have better syntax, something like:

config.merge("a.b",config.getConfig("b1"))

allow value-concatenating an object to each list element

  1. this is a feature request

  2. use case:

  • imaging you have network service with some 100 end points;
  • each end point has some 30 parameters, mostly common to all points;
  • may be 2 to 5 of the parameters are to be overridden by each point;
  1. the way I understand current mechanisms of HOCON
    https://github.com/typesafehub/config/blob/master/HOCON.md
    this would make this definition very verbose;

  2. how about new/proposed object$builder syntax:

//
// the list definition below will be looking for this builder
//
netty_point_list$builder {
   id = "you-must-override"
   localAddress = "1.2.3.4:12345"
   remoteAddress = "you-must-override"
   packetTTL = 5
   pipeline = "default-pipeline"
   pipeline_param_0 = 123
   // 20 more parameters here; mostly come from include  or variable substitution
}

//
// netty_point_list will be looking for optional netty_point_list$builder
// to initialize default list items parameters before override
//
netty_point_list [
   { id = "service-1", remoteAddress = "1.1.1.1:12345", pipeline = "advanced" }
   { id = "service-2", remoteAddress = "1.1.1.2:12345", localAddress = "3.3.3.3:12345" }
   // 100 more service definitions with little variations on the builder-defined parameters
]
  1. am I missing some HOCON feature or what? :-)

Use context class loader by default

Right now to load the reference config, etc. we use getClassLoader on a class from com.typesafe.config

But for example Play is trying to do this:

private val initialConfiguration = Threads.withContextClassLoader(classloader) {
    Configuration.load(path, mode)
}

And because Play apps have their own class loader, the reference.conf for the app dependencies will not be found.

The config library should use the context class loader by default rather than ConfigImpl.class.getClassLoader.

migrate to antlr / javacc

just an after thought:

based on the little experience with pull 32

I can say its a bit hard to understand which parts of hocon gramma
are processed by what and if that processing is complete / non contradictory

I wish you would migrate that part of the library to antlr
or javacc by the time of 2.0.0 :-)

include classpath() not respected in Windows

When I have an external config file on my Linux box which has an include classpath('application') everything works as expected, but when I run the same program on a Windows 7 machine, I get a flurry of exceptions saying that I can't use an unquoted string in the include statement. Any thoughts?

Substitutions don't honor latest value

HOCON.md says the following about substitutions:

Substitution processing is performed as the last parsing step, so a substitution can look forward in the configuration. If a configuration consists of multiple files, it may even end up retrieving a value from another file.

If a key has been specified more than once, the substitution will always evaluate to its latest-assigned value (that is, it will evaluate to the merged object, or the last non-object value that was set, in the entire document being parsed including all included files).

My reference.conf contains:

foo = hello/${bar}
bar = world

My application.conf contains:

bar=mother

What should the output of the following code be after loading the configuration:

        System.out.println(config.getString("foo"));
        System.out.println(config.getString("bar"));

I would expect "hello/mother" and "mother". Instead, I see "hello/world" and "mother". Did I misunderstand what the spec says about substitutions being evaluated as a last step or is there a bug here?

Parse String[] args commandline parameter

A nice feature would be to parse commandline parameters. E.g.

-db.user=muki -db.password=secret
public static void main(String[] args) {
   Config c = ConfigFactory.parseArray(args).getConfig("db");
   c.getString("user");
   c.getString("password");
}

If there is any interest, I would try to provide an implementation.

Serialization problem using JBossSerialization

Using JBossObjectOutputStream and JBossObjectInputStream results in an EOFException.
The main problem is that trying to call an EJB3-method on a bean in another EAR on a jboss server (jboss as 5.1) results in an IOException:

at org.jboss.aop.joinpoint.ConstructionInvocation.invokeNext(ConstructionInvocation.java:79)
at org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
at org.jboss.aop.joinpoint.ConstructionInvocation.invokeNext(ConstructionInvocation.java:79)
at org.jboss.ejb3.EJBContainer.invokeCallback(EJBContainer.java:1119)
... 66 more
Caused by: java.io.IOException: field code 0 is not supposed to be on the wire
at com.typesafe.config.impl.SerializedConfigValue.readCode(SerializedConfigValue.java:414)
at com.typesafe.config.impl.SerializedConfigValue.readOrigin(SerializedConfigValue.java:218)
at com.typesafe.config.impl.SerializedConfigValue.readValue(SerializedConfigValue.java:392)
at com.typesafe.config.impl.SerializedConfigValue.readExternal(SerializedConfigValue.java:453)
at org.jboss.serial.persister.ExternalizePersister.readData(ExternalizePersister.java:72)
at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.readObjectDescriptionFromStreaming(ObjectDescriptorFactory.java:412)
at org.jboss.serial.objectmetamodel.ObjectDescriptorFactory.objectFromDescription(ObjectDescriptorFactory.java:82)
at org.jboss.serial.objectmetamodel.DataContainer$DataContainerInput.readObject(DataContainer.java:845)
at org.jboss.serial.io.MarshalledObjectForLocalCalls.get(MarshalledObjectForLocalCalls.java:60)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invokeLocal(IsLocalInterceptor.java:101)
at org.jboss.ejb3.remoting.ClusteredIsLocalInterceptor.invoke(ClusteredIsLocalInterceptor.java:52)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
at org.jboss.aspects.remoting.PojiProxy.invoke(PojiProxy.java:62)
at $Proxy1483.invoke(Unknown Source)
at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:207)
at org.jboss.ejb3.proxy.impl.handler.session.SessionProxyInvocationHandlerBase.invoke(SessionProxyInvocationHandlerBase.java:164)
... 80 more

Unfortunately I haven't been able to figure out exactly why the exception occurs.
Using a newer version of jboss-serialization is no solution...

Allow objects without braces around them inside arrays

I would propose to extend the HOCON syntax to simplify declaration of an array of objects.

Currently it is possible to declare an array of primitive types or objects like the following:

[ 3, 6, 9 ]

[ alpha, beta, delta ]

[
   { a : 42, c : 5 }
   { b : 43, c : 6 }
]

But take in consideration the declaration of a list of assignments, for example: alpha = 1, beta = 2, delta = 3. Currently it is required the following definition:

 [  { alpha = 1 } , { beta = 2 }, { delta = 3 } ]

It is much nicer if it would be possible to use the following syntax

[  alpha =  1, beta = 2, delta = 3   ] 

The benefit is more evident for more complex declaration like this

[  alpha =  { a:1 }, beta = { b: 2 }, delta = { c: 3, d: 4 )   ] 

instead of

[  { alpha =  { a:1 } }, { beta = { b: 2 } }, { delta = { c: 3, d: 4 } }  ] 

The underlying would not change but the syntax would be much more readable in the spirit of the project.

Thanks

systemProperties question

Hi,I use
val conf = ConfigFactory.load("cmds", ConfigParseOptions.defaults().setSyntax(ConfigSyntax.PROPERTIES),ConfigResolveOptions.noSystem())

"cmds" is properties file.

but always load systemProperties,fox example

awt.toolkit
os.version
java.vendor.url.bug
java.awt.graphicsenv
java.home
line.separator
java.vm.version
java.vm.specification.name
sun.management.compiler
java.vm.info

......

I think only load myself properties,don't need systemProperties,So what am I, what am I to do?

Thanks!

xml round trip codec

this is a feature request;

I suggest to incorporate into typesafe.config ability to import(also export) external xml config files

sample implementation:
https://github.com/barchart/barchart-config/blob/master/barchart-conf-util/src/main/java/com/barchart/conf/util/ConfigXML.java

sample xml source:
https://github.com/barchart/barchart-config/blob/master/barchart-conf-util/src/test/resources/reference/hazelcast-fullconfig.xml

sample typesafe.config result:
https://github.com/barchart/barchart-config/blob/master/barchart-conf-util/src/test/resources/reference/hazelcast-fullconfig.conf

basic idea is to overload symbol "/" with semantics : "reference to xml node attribute or parent node value"

Configuring akka serialization in Play 2.0 framework

Hi guys,

I'd like to configure protobuf to be the default serialization for my messages.
Here what I do in attempt to make it happen:

import akka.actor._
import akka.pattern.ask
import akka.serialization._
import akka.util._
import play.api._
import play.libs.Akka
import akka.util.Timeout

object Engine {
implicit val timeout = Timeout(1 second)
val ngin = Akka.system.actorOf(Props[Engine])
}

class Engine extends Actor {
val ser = SerializationExtension(context.system)
override def preStart() = {
println("Got %s serializer for %s"
.format(ser.findSerializerFor(classOf[java.lang.String]).getClass().getName(),
classOf[java.lang.String].getName()))
}
def receive = { ... }
}

While my application.conf file contains the following section:

play { akka { actor {
serializers { proto = "akka.serialization.ProtobufSerializer" }
serialization-bindings { "java.io.Serializable" = proto
"java.lang.String" = proto }
} } }

Though I always get JavaSerializer: "Got
akka.serialization.JavaSerializer serializer for java.lang.String"
What am I doing wrong?!

-Matthew

Appending arrays isn't supported

If you try to append arrays using the shorthand syntax += as described in README.md, you get the following exception:

Reserved character '+' is not allowed outside quotes (if you intended '+' to be part
of a key or string value, try enclosing the key or value in double quotes)

Support multi-line unquoted strings

I know the documentation explicitly says that "multi-line unquoted strings using backslash to continue the line are not allowed". But, unless there is a good reason for not supporting it, this would be a very convenient feature.

Support ".hocon" extension

This library can be used not only for the configuration, but also for many other purposes. But you support extension ".conf" only when activated HOCON by default. I think the extension ".hocon" is necessary for load by default in HOCON format.

Parse exception for key jvm.memory

Am using Play 1.2.x where my application.conf has a key (jvm.memory) with the following value

jvm.memory=-Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=256M

Got a Parse exception ConfigFactory.load(), the message is as follows -

A com.typesafe.config.ConfigException$Parse has been caught, application.conf: 64: Invalid number: '-' (if you intended '-' to be part of the value for 'jvm.memory', try enclosing the value in double quotes, or you may be able to rename the file .properties rather than .conf)

Any workaround? Play does not like when I try enclosing the value with double quotes.

Parse exception for key jpa.entities

Am using Play 1.2.x. I need to declare a long list of JPA entities, however Config does not like it. Below is an example

jpa.entities=com.googlecode.sarasvati.hib.HibArc, com.googlecode.sarasvati.hib.HibArcToken

Below is the Parse exception
A com.typesafe.config.ConfigException$Parse has been caught, application.conf: 147: Key 'com.googlecode.sarasvati.hib.HibArcToken' may not be followed by token: ',' (if you intended ',' to be part of the value for 'com.googlecode.sarasvati.hib.HibArcToken', try enclosing the value in double quotes)

There is no getSeconds API

There is a getMilliseconds and getNanoseconds API, but no getSeconds API. Seems like this would be useful for many people and trivial to add.

hocon for dummies

I just did a little edit of HOCON.md for pull 32

what struck me it is a classic tl;dr masterpeace

I suggest to provide hocon for dummies which would be
just a collection of small hocon config snippets, with minimal comments,
of increasing complexity, so people can pick up and use hocon patterns,
w/o much technical understanding of details

failed to resolve system property

I tried to ${user.home} in my project, but got a ConfigException$UnresolvedSubstitution error, however, it's ok to use something like ${HOME}

assertNotNull(System.getProperty("user.home"));

String conf = "foo: bar, home: ${HOME}, myHome: ${user.home}";
Config cfg = ConfigFactory.parseReader(new StringReader(conf));

assertEquals("bar", cfg.getString("foo"));
assertFalse(cfg.resolve().getString("home").contains("$")); // works
assertFalse(cfg.resolve().getString("myHome").contains("$")); // failed

checkValid is broken

the following little test
https://github.com/barchart/barchart-inst/blob/master/barchart-inst-store-sql/src/test/java/typesafe/TestCheckValid.java

    @Test
    public void test() {

        //

        final Config reference = ConfigFactory.defaultReference();

        final Config memberONE = reference.getConfig("member-config");

        log.debug("memberONE : {}", memberONE);

        /** good config - should pass */
        memberONE.checkValid(reference, "member-config");

        memberONE.getBoolean("is-master");

        //

        final String configWithTypeError = "{ is-master = 42 }";

        final Config memberTWO = ConfigFactory.parseString(configWithTypeError)
                .withFallback(memberONE);

        log.debug("memberTWO : {}", memberTWO);

        /** sick config - should fail */
        memberTWO.checkValid(reference, "member-config");

        memberTWO.getBoolean("is-master");

        assertTrue(true);

    }

and a reference
https://github.com/barchart/barchart-inst/blob/master/barchart-inst-store-sql/src/main/resources/reference.conf

member-config {
    is-master = false
    name = unknown
    batch-size = 100
}

fails self-check here

        /** good config - should pass */
        memberONE.checkValid(reference, "member-config");

with a trace:

com.typesafe.config.ConfigException$ValidationFailed: reference.conf: 2: member-config: No setting at 'member-config', expecting: object with keys [batch-size, is-master, name]
    at com.typesafe.config.impl.SimpleConfig.checkValid(SimpleConfig.java:833)
    at typesafe.TestCheckValid.test(TestCheckValid.java:28)

what am I missing ?

Sending Config Object Over the Wire

Thanks for writing this library and for documenting it so well. It is great and is helping us manage our config files better.

I'm using it in a system which centralizes the configuration of various other services. We need to send com.typesafe.config,Config objects over the wire to other services. What I'd like to do is the following:

  1. Get string representation of a config object. Something like:
    val conf = configObject.getConfString;
  2. And on the client side, simply do:
    ConfigFactory.parseString(conf)

So, my question is, given a config object, is there a simple way to get to its string representation?

convenience getXXX() with default

this is a feature request;

currently, the pattern like this is hard to avoid:

if (config.hasPath("master")) {
    return config.getBoolean("master");
} else {
    return false;
}

it would help to have conviniece getXXX() with default, such as:

    return config.getBoolean("master", false);

config diff?

hello;

  1. I am considering delivering of configuration changes
    in a form of com.typesafe.config.Config based events;

  2. this would need some form of
    typesafe.config.Diff(old,new) -> diff

  3. what would be the fast, low heap, and "right"
    way to do this config diff?

  4. can this be generic enough to warrant inclusion
    in the typesafe.config library?

thanks.

jacoco4sbt 1.2.2 cannot be resolved

I cannot build this snapshot due to this error:
unresolved dependency: de.johoop#jacoco4sbt;1.2.2

I changed the sbt version from 0.11.2 to 0.11.3, but
this shouldn't caused this problem?

Furthermore I tried
addSbtPlugin("de.johoop" % "jacoco4sbt" % "1.2.3")
Which can be resolved but leads to an ClassNotFound exception

[feature] Provide hook to force refresh of system properties

From the Javadoc of ConfigFactory.systemProperties:

"Because this returns a singleton, it will not notice changes to system properties made after the first time this method is called"

While this makes sense, I'm running into a problem where a hook to force refresh of system properties would help. Specifically, I'm building a Config object via Guice-injection, which is then used to populate a "settings" object (as suggested in the README). For unit tests, we construct a new settings object per test so we can specify different settings for each test.

Unfortunately, because of the above behavior of systemProperties (and hence, defaultOverrides and load), any test that modifies system properties can have unintended side effects on subsequent tests.

com.typesafe.config.impl.SerializedConfigValue should be exported in OSGi manifest

Now the com.typesafe.config.impl package is defined as private, which prevents akka 2.0 from working in remote scenarios with remote deployment. The reason for this is that the com.typesafe.config.impl.SerializedConfigValue class is not available for the akka.remote.MessageSerializer:

    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:513)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:622)
    at akka.util.ClassLoaderObjectInputStream.resolveClass(ClassLoaderObjectInputStream.scala:12)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1593)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1964)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1888)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at akka.serialization.JavaSerializer$$anonfun$1.apply(Serializer.scala:121)
    at scala.util.DynamicVariable.withValue(DynamicVariable.scala:57)
    at akka.serialization.JavaSerializer.fromBinary(Serializer.scala:121)
    at akka.serialization.Serialization.deserialize(Serialization.scala:73)
    at akka.remote.MessageSerializer$.deserialize(MessageSerializer.scala:22)
    at akka.remote.RemoteMessage.payload(RemoteTransport.scala:212)
    at akka.remote.RemoteMarshallingOps$class.receiveMessage(RemoteTransport.scala:274)
    at akka.remote.netty.NettyRemoteTransport.receiveMessage(NettyRemoteSupport.scala:46)
    at akka.remote.netty.RemoteServerHandler.messageReceived(Server.scala:182)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75)
    at akka.remote.netty.RemoteServerHandler.handleUpstream(Server.scala:154)
    at org.jboss.netty.channel.StaticChannelPipeline.sendUpstream(StaticChannelPipeline.java:372)
    at org.jboss.netty.channel.StaticChannelPipeline$StaticChannelHandlerContext.sendUpstream(StaticChannelPipeline.java:534)
    at org.jboss.netty.handler.execution.ChannelUpstreamEventRunnable.doRun(ChannelUpstreamEventRunnable.java:45)
    at org.jboss.netty.handler.execution.ChannelEventRunnable.run(ChannelEventRunnable.java:69)
    at org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor$ChildExecutor.run(OrderedMemoryAwareThreadPoolExecutor.java:315)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

Thanks for looking into this!

LoaderCache not thread safe?

On just one not-yet-reproduced occasion, this test failed:

[error] Test com.typesafe.config.impl.PublicApiTest.cachedReferenceConfig failed: defaultReference(loader) was cached

cache.getOrElseUpdate is synchronized, it isn't clear to me what could be wrong.

ConfigException lies about being Serializable, contains non-serializable ConfigOrigin

if we have a client report a ConfigException we get a message instead:

cannot serialize: com.typesafe.config.ConfigException$WrongType: system properties: user has type OBJECT rather than STRING))) due to java.io.NotSerializableException: com.typesafe.config.impl.SimpleConfigOrigin

seems trivial to add "implements Serializable" to either the ConfigOrigin interface or the SimpleConfigOrigin class

our ref: PERF-463

[feature] Enhance checkValid for negative checks

One of the contracts of checkValid is "All paths found in the reference config must be present in this config or an exception will be thrown."

IMO the converse is also very useful: "If a path is found in this config that is NOT present in the reference config, an exception will be thrown".

Use cases:

  • User specifies an "unknown" property in the config. So reference has "foo.bar" but user specific "foo.baz" -- I'd like to present the user with a useful error message in this case, via checkValid
  • User makes a spelling mistake in specifying a known property, resulting in unexpected/surprising behavior. So reference has "foo.config" but user by mistake says "foo.confg" -- checkValid passes in this case leaving the user wondering what went wrong

Concatenated strings as keys

Given the following:

repositories {
    AWS S3 : "http://jets3t.s3.amazonaws.com/maven2"
}

The key is parsed as ""AWS S3"" instead of "AWS S3", which is what I expected from reading the README.

Accessing default application.config from resources using Scala IDE

Hi,

I'm attempting to load a default application config while running my project in Scala IDE. Everything works great if I run the application via sbt at the CLI, but when I try to start my application in Scala IDE using the Scala Application loader it's unable to find the configuration file.

I've placed my application configuration file in my project at the following path.

/src/main/resources/application.conf

My calling code is simply ConfigFactory.load().getString("bar") from my main method and I get the following stack trace.

Exception in thread "main" java.lang.ExceptionInInitializerError
at com.foo.dataservices.MyServer.main(MyServer.scala)
Caused by: com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'bar'
at com.typesafe.config.impl.SimpleConfig.findKey(SimpleConfig.java:115)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:138)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:150)
at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:155)
at com.typesafe.config.impl.SimpleConfig.getConfigNumber(SimpleConfig.java:170)
at com.typesafe.config.impl.SimpleConfig.getInt(SimpleConfig.java:181)

Any help would be appreciated.

ConfigImpl doesn't respect key order

This is a very simple use case: A list of common steps (configuration for scheduling, processing order etc.) with inter-dependent order is configured using namespaced keys, like this:

tasks.prepare.args="collect,store"
tasks.process.args="count"
tasks.cleanup.args="deleteTemps"

Expected: When iterating the keys under tasks, the order is [prepare, process, cleanup].
Actual: Dependent on JDK's HashMap implementation.

The simplest fix for this would be to use LinkedHashMap instead. As a workaround I now need to add a number as additional key to each task and then sort afterwards the objects created based on the configuration using that number to get them into order I want to.

include base(); "config://" url handler;

hello;

  1. this is a feature request;

  2. currently, include url()/file()/classpath()
    https://github.com/typesafehub/config/blob/master/HOCON.md#includes

are either relative or absolute, to the specific url:
"otherwise, a file or other resource "adjacent to" the one being parsed"

  1. I suggest to introduce a concept of a "base()" stanza:
    include base("common/server/instance/settings.conf")
    witch represents an idea: include form a root of "common configuration store",
    and is agnostic of url()/file()/classpath() distinctions;

  2. "configuration store" would have to be a new concept for typesafe.config;

  3. base() url handler would have to be provided to the typesafe.config library
    in some external way

  4. another alternative would be to rely on new custom "config://" protocol handler
    explicitly, such as, in this stanza:
    include url("config://common/server/instance/settings.conf")

  5. an example of custom url approach can be found here:
    https://github.com/barchart/barchart-config/tree/master/barchart-conf-base
    https://github.com/barchart/barchart-config/blob/master/barchart-conf-base/src/main/java/com/barchart/conf/impl/ConfigHandlerProvider.java

  6. the benefit of "include base()" in typesafe.config would be to standardize
    the "configuration store" approach to configuration management;

thank you.

Config should allow for default values.

Config interface should allow for default values to be defined in code such that if not present in config file the value defined in code can be picked up.

val a = config. getInt("a.b.c",10) //If a.b.c is not defined 10 will be applied.

tweak hocon-formatted render (was: ConfigRenderOption for HOCON)

Hi,

I can use config.root.render(ConfigRenderOptions.concise.setFormatted(true)) for dumping my Config to JSON format, but that would be really great to be able to dump in to HOCON format.

I'm very fond of this lib, and I'd like to use it, not only for read-only config, but also for read-write preferences that are dumped on the filesystem.

Cheers,

Stéphane

Please push this to maven central

I would like to use this library in a couple open source projects. Unfortunately, maven being what it is, if someone uses my library as a dependency, and my library depends on this one, then the transitive dependency fails because my users don't have your maven repo configured. The easiest way to resolve this is to push artifacts from this library into maven central.

Yes, this is a maven design flaw, but supporting existing maven stuff is a feature worth supporting.

toStringJSON

can you please carry in the library this little thingy (or, better, non-static)?


    private static final ConfigRenderOptions FORMAT = ConfigRenderOptions
            .concise().setFormatted(true);

    public static String toStringJSON(final Config config) {

        return toStringJSON(config.root());

    }

    public static String toStringJSON(final ConfigObject object) {

        return object.render(FORMAT);

    }

thanks.

support string and object in value concatenation

The README proposes extending the string value concatenation to arrays and objects. So

${foo} "hello"

concats ${foo}'s value with "hello", with arrays

${foo} [1,2,3]

prepends ${foo} to the array, and with objects it would merge the two, so

${foo} { name = "east" }

would merge { name = "east" } into ${foo}

This would among other things give a nicer syntax when "inheriting", before:

data-center-east = ${data-center-generic}
data-center-east = { name = "east" }

after:

data-center-east = ${data-center-generic} { name = "east " }

also, if substitutions are allowed to refer to the previous value of the field being defined, you could use this to extend paths.

 path = [somethingBefore] ${path} [somethingAfter]

For more bonus points, support +=:

path += somethingAfter

equivalent to

 path = ${path} [somethingAfter]

Missing includer

Hi,

is there any plan to implement the missing parsing option in the com.typesafe.impl.Parser below?

                if (kind.equals("url(")) {

                } else if (kind.equals("file(")) {

                } else if (kind.equals("classpath(")) {

                } else {
                    throw parseError("expecting include parameter to be quoted filename, file(), classpath(), or url(). No spaces are allowed before the open paren. Not expecting: "
                            + t);
                }

or was there a specific reason why it was not implemented? This would be really useful when running play2.0 apps where we would only like some of the configuration options in the binary exposed. Right now includes will resolve to the base of the original URL with no option to include from another source.

I am more than happy to try and add this myself, just trying to find out the rationale for not implementing it initially.

Thanks

path expression to access array elements directly

Is there a way to access an array element directly?
example:

arr [
  {ip= 192.168.7.1, name="Server 1"},
  {ip= 192.168.7.2, name="Server 2"},
  {ip= 192.168.7.3, name="Server 3"}
]

As far as I understand the library I first have to access the array by calling config.getObjectList("arr") and then iterating over the list to access the fields of my objects.
I'd like to have the possibility of calling config.getString("arr[0].ip") or something like that...

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.