tag:blogger.com,1999:blog-67109868418445686862024-03-19T04:18:27.215-07:00Java ConfigurationBlog dedicated to Java Configuration in SE and EE.Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.comBlogger15125tag:blogger.com,1999:blog-6710986841844568686.post-87208310240177796752015-09-07T11:26:00.000-07:002015-09-07T13:04:41.384-07:00Apache Tamaya - the new Configuration API<span style="font-family: Arial, Helvetica, sans-serif;">It was quite s long time since I have blogged here, but now it is definitive time to reactivate this blog and get in contact with all interested people on the configuration topic.</span><br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">History</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">After JavaOne 2014, when the configuration topic was cancelled from the EE8 list, David Blevins and others proposed to start an Apache project for several reasons:</span><br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">let focus people with experience in the topic to identify a common feature set</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">implement the ideas as part of an Apache project to provide the ideas using a free nd redistributable licence</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">use a common proven organisation also capable of generating successful adoption.This was when </span><a href="http://tamaya.incubator.apache.org/" target="_blank"><span style="font-family: Arial, Helvetica, sans-serif;">Apache Tamaya </span></a><span style="font-family: Arial, Helvetica, sans-serif;">was put to incubation. Following we had several discussions, hangouts, mails. As a result </span><a href="http://tamaya.incubator.apache.org/" target="_blank"><span style="font-family: Arial, Helvetica, sans-serif;">Apache Tamaya</span></a><span style="font-family: Arial, Helvetica, sans-serif;"> is now available as a first release </span><i><span style="font-family: Arial, Helvetica, sans-serif;">0.1-incubating</span></i><span style="font-family: Arial, Helvetica, sans-serif;">, ready to be used.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Also to be mentioned is that also Mark Struberg and Gerhard Petracek, the guys behind Deltaspike, joined this project and actively contributed to it. Given that I think it is worth to have a deeper look at the project. This is what this blog is all about.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">The Apache Tamaya Project</span></h3>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Like a Java Specification Request</span></h4>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><a href="http://tamaya.incubator.apache.org/" target="_blank"><span style="font-family: Arial, Helvetica, sans-serif;">Apache Tamaya </span></a><span style="font-family: Arial, Helvetica, sans-serif;"></span>is built-up similarly to a Java Specification Request (JSR). It as an API that defines the artifacts user's typically interact with and it provides a reference implementation that implements the API so it can be used for real world projects. The reason for doing so are the following:</span></div>
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Separating an API from the implementation gives you a very clear and clean view on the problem. You must isolate the essence of your problem and omit all kind of over-specific aspects. If done in a good way, this leads to a simple and well comprehensive API, which at the same time is powerful enough to support at least most of all other requirements (e.g. using extension points or hooks for plugin in adapted or additional </span><span style="font-family: Arial, Helvetica, sans-serif;">functionality (aka service provider interfaces/SPIs).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The API may be more independent than the reference implementation regarding its compatibility requirements. As an example the Java 7 based API of Apache Tamaya in fact is also compatible Java 6 and Java ME platforms.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">You can start with a minimal set of functionality on the API and extending it step-by-step as needed. Very extension must be checked, if it is really necessary or if the requirement not also can be implemented using the existing API/SPI. This ensures your API is really focusing on the minimal aspects thefore getting lean and clear.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Last but not least, somehow corresponding to the previous point, adding new functionality does not interfere with the basic API/implementation, making it very easy to add new functionality. The Apache Tamaya project also contains quite a few of so called extensions that only depend on the API, so the project has already proven being able to cover this aspect very efficiently.</span></li>
</ol>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The only difference to a JSR is the current lack of a Technical Compatibility Kit (TCK) that ensures that different implementations of the API are compatible with a common set of rules. Similarly we do not have something like a "specification" (but we have a very extensive documentation, somehow quite similar to a specification, also covering many of the aspects/discussions done during the evaluation phase for the Java EE JSR 2 years ago).</span></div>
<div>
<br /></div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Compatibility</span></h4>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><a href="http://tamaya.incubator.apache.org/" target="_blank"><span style="font-family: Arial, Helvetica, sans-serif;">Apache Tamaya </span></a><span style="font-family: Arial, Helvetica, sans-serif;"></span>currently supports both Java 7 and Java 8. Reasons behind is that there is still plenty of code, especially in the enterprise context, running on Java 7. And we wanted people to be able to use Apache Tamaya also before they move to the Java 8 platform. Said that the API can be added to your maven build quite easily:</span></div>
<div>
<br /></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"><dependency></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <groupId>org.apache.tamaya</groupId></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <artifactId>tamaya-java7-api</artifactId></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <version>0.1-incubating</version></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"></dependency></span></div>
<div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Or, when with Java 8:</span></div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"><dependency></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <groupId>org.apache.tamaya</groupId></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <artifactId>tamaya-api</artifactId></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <version>0.1-incubating</version></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"></dependency></span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Similarly the implementation (called core), can be added similarly:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Compatible with Java 7 and beyond:</span></div>
<div>
<br /></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"><dependency></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <groupId>org.apache.tamaya</groupId></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <artifactId>tamaya-java7-core</artifactId></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <version>0.1-incubating</version></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"></dependency></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Compatible with Java 8:</span></div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"><dependency></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <groupId>org.apache.tamaya</groupId></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <artifactId>tamaya-core</artifactId></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> <version>0.1-incubating</version></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"></dependency></span></div>
<span style="font-family: Courier New;"></span></div>
<div>
<b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><span style="font-family: Courier New;"><br /></span></div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">The Main Concepts</span></h3>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Configuration Abstraction and Access </span></h4>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">One of the main objectives is to define an abstraction for configuration and define a common way of accessing it using simple Java code. So the first thing is to define a model for configuration:</span></div>
<div>
<br /></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"><b>public interface</b> Configuration {<br /><br /> <b>default</b> String get(String key) {...}<br /> <b>default</b> <T> T get(String key, Class<T> type) {...}<br /> <b>default</b> Configuration with(ConfigOperator operator) {...}<br /> <b>default</b> <T> T query(ConfigQuery<T> query) {...}<br /><br /> <T> T get(String key, TypeLiteral<T> type);</span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> Map<String, String> getProperties();</span></div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New;"> </span><span style="color: #38761d; font-family: Courier New;">// not available for Java 7</span><span style="font-family: "Courier New", Courier, monospace;"><br /> <b>default</b> Optional<String> getOptional(String key) {...}<br /> <b>default</b> <T> Optional<T> getOptional(String key, <br /> Class<T> type) {...}<br /> <b>default</b> <T> Optional<T> getOptional(String key, <br /> TypeLiteral<T> type) {...}<br /> <b>default</b> Optional<Boolean> getBoolean(String key) {...}<br /> <b>default</b> OptionalInt getInteger(String key) {...}<br /> <b>default</b> OptionalLong getLong(String key) {...}<br /> <b>default</b> OptionalDouble getDouble(String key) {...}<br />}</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So looking at this interface some important key decisions can be identified:</span></div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration entries are accessed using <span style="font-family: "Courier New", Courier, monospace;">String</span> keys.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration values are basically modelled as Strings</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Typed access is supported as well using <span style="font-family: "Courier New", Courier, monospace;">Class</span> or <span style="font-family: "Courier New", Courier, monospace;">TypeLiteral</span>.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration can be accessed key by key or by accessing the full properties map (<i>getProperties</i>). Hereby there is a constraint that the returned map may not contain all entries that would also be available when accessing them individually. Reason is that some configuration sources may not be able to list all the entries (aka being </span><i><span style="font-family: Arial, Helvetica, sans-serif;">scannable</span></i><span style="font-family: Arial, Helvetica, sans-serif;">). Refer also the SPI part, when the <span style="font-family: "Courier New", Courier, monospace;">PropertySource</span> interface is discussed, for further details.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The methods <i>with, query</i> define so called functional extension points, allowing additional functionality being added as operators/queries that can be applied on a configuration.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Finally, only defined in the API version depending on Java 8, are all the methods returning <span style="font-family: "Courier New", Courier, monospace;">Optional</span> values. These add support for the new <span style="font-family: "Courier New", Courier, monospace;">Optional</span> artifact introduced with Java 8. Similarly all the <span style="font-family: "Courier New", Courier, monospace;">default</span> methods were replaced in the Java 7 variant with corresponding abstract base implementations shipped with the reference implementation.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Instances of Configuration can be accessed from a <span style="font-family: "Courier New", Courier, monospace;">ConfigurationProvider</span> singleton:</span></div>
<div>
<br /></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;">Configuration config = ConfigurationProvider.getConfiguration();</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Hereby always a valid instance must be returned. It is </span><b><span style="font-family: Arial, Helvetica, sans-serif;">not</span></b><span style="font-family: Arial, Helvetica, sans-serif;"> required that always the same instance is returned. Especially when running in a contextual environment, such as Java EE, each context may return different configurations, also reflecting the configuration resources deployed in the different Java EE artifacts. Similarly also OSGI based environments have their own classloader hierarchies, that may require isolation of configuration along the classloader bounderies.</span></div>
<div>
<br /></div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Functional Extension Points</span></h4>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">In the previous section we already mentioned the methods <i>with</i> and <i>query</i>. These take as argument a <span style="font-family: "Courier New", Courier, monospace;">ConfigurationOperator</span> or a <span style="font-family: "Courier New", Courier, monospace;">ConfigurationQuery<T>,</span> which are defined as follows:</span></div>
<div>
<br /></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;">@FunctionalInterface<br /><b>public interface</b> ConfigOperator {<br /> Configuration operate(Configuration config);<br />}</span></div>
<div>
<br /></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;">@FunctionalInterface<br /><b>public interface</b> ConfigQuery<T> {<br /> T query(Configuration config);<br />}</span></div>
<div>
<b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So basically <span style="font-family: "Courier New", Courier, monospace;">ConfigOperator</span> acts as a mapping that derives a <span style="font-family: "Courier New", Courier, monospace;">Configuration</span> from another <span style="font-family: "Courier New", Courier, monospace;">Configuration</span>, whereas a <span style="font-family: "Courier New", Courier, monospace;">ConfigurationQuery<T></span> can return any kind of result. Both constructs allow adding functionality in multiple ways without having to deal with it on the Configuration interface, e.g. aspects like:</span></div>
<span style="font-family: Arial, Helvetica, sans-serif;"></span><br />
<ul><span style="font-family: Arial, Helvetica, sans-serif;">
<li>Filtering of configuration for specific use cases, e.g. recombining entries, or removing entries out of scope for a certain use case</li>
<li>Masking of entries or sections for security reasons</li>
<li>Creating typed objects based on configuration</li>
<li>Statistical details on a given configuration, e.g. the defined sections</li>
<li>Configuration validation and documentation</li>
<li>Conversion of configuration, e.g. to a JSON representation</li>
<li>and much more.</li>
</span></ul>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">For running examples you may consider having a look at the<i> tamaya-functions</i> extension module, which already implements quite a few of aspects.</span></div>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">
<span style="font-family: Arial, Helvetica, sans-serif;">A minimalistic Example</span></span></h4>
<span style="font-family: Arial, Helvetica, sans-serif;">
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"></span>To clarify things a bit more let's create a small example, which just uses the base mechanism provided with Tamaya's core implementation. Let's assume we build a small node, that a micro-service performing a simple compound interest rate calculation (I will omit the financial details how this is achieved here). Such a calculation basically is defined as:</div>
<div>
<br /></div>
<div>
We assume that the interest rate is something that is configured for this component, so in our component we simply add the following code:</div>
<div>
<br /></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;">BigDecimal interestRate = ConfigurationProvider.getConfiguration()<br /> .get("com.mycomp.ratecalculator.rate",<br /> BigDecimal.<b>class</b>);</span></div>
<div>
<br /></div>
<div>
When using Java 8 we could also easily combine it with a default value:</div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;">BigDecimal interestRate = ConfigurationProvider.getConfiguration()<br /> .getOptional("com.mycomp.ratecalculator.rate", <br /> BigDecimal.<b>class</b>)<br /> .orElse(BigDecimal.of(0.05d));</span></div>
<div>
<br /></div>
<div>
Given that we can easily implement our business logic, also using the JSR 354 type (see <a href="http://javamoney.org/">http://javamoney.org</a>):</div>
<div>
<br /></div>
<div>
<b><span style="font-family: "Courier New", Courier, monospace;">public class</span></b><span style="font-family: "Courier New", Courier, monospace;"> MyRateCalculator <b>implements</b> RateCalculator{</span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> </span><b><span style="font-family: "Courier New", Courier, monospace;">private</span></b><span style="font-family: "Courier New", Courier, monospace;"> </span><span style="font-family: "Courier New", Courier, monospace;">BigDecimal interestRate = ConfigurationProvider<br /> .getConfiguration()<br /> .getOptional("com.mycomp.ratecalculator.rate", <br /> BigDecimal.</span><b><span style="font-family: "Courier New", Courier, monospace;">class</span></b><span style="font-family: "Courier New", Courier, monospace;">)<br /> .orElse(BigDecimal.of(0.05d));</span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> </span><b><span style="font-family: "Courier New", Courier, monospace;">public</span></b><span style="font-family: "Courier New", Courier, monospace;"> MonetaryAmount calcRate(MonetaryAmount amt, </span><b><span style="font-family: "Courier New", Courier, monospace;">int</span></b><span style="font-family: "Courier New", Courier, monospace;"> periods){</span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"> }</span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace;">}</span></div>
<div>
<br /></div>
<div>
Now given you have built your logic in a similar way you have multiple benefits:</div>
<ul>
<li>You can deploy your calculator as part of a Desktop application.</li>
<li>You can deploy your calculator as part of a Java EE application.</li>
<li>You can deploy your calculator in an OSGI container.</li>
<li>You can deploy your calculator easily as a standalone micro-service (with an appropriate API, e.g. REST).</li>
</ul>
</span><span style="font-family: Arial, Helvetica, sans-serif;"><div>
<br /></div>
</span><br />
<div>
<br /></div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Making Tamaya Support Optional</span></h4>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically you can even use the Tamaya optional module to integrate with Tamaya only as an optional dependency. This extension module is a very simple module, adding basically only one class to your dependency path, which</span></div>
<b></b><i></i><u></u><sub></sub><sup></sup><strike></strike><br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Ensures Tamaya API is on your classpath</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Optionally checks if a <span style="font-family: "Courier New", Courier, monospace;">Configuration</span> is accessible from a given context.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Delegates <span style="font-family: "Courier New", Courier, monospace;">Configuration</span> request to Tamaya, or - if not availalbe - to a delegate passed from your logic, when creating the delegate:</span></li>
</ul>
<div>
<span style="font-family: "Courier New", Courier, monospace;"><b>import</b> org.apache.tamaya.ext.optional.OptionalConfiguration;</span></div>
<div>
<br /></div>
<div>
<b><span style="font-family: "Courier New", Courier, monospace;">private</span></b><span style="font-family: Arial;"><span style="font-family: "Courier New", Courier, monospace;"> </span><span style="font-family: "Courier New", Courier, monospace;">BigDecimal interestRate = </span></span><br />
<span style="font-family: Arial;"><span style="font-family: "Courier New", Courier, monospace;"> Optional.ofNullable(<br /> OptionalConfiguration</span></span><span style="font-family: Arial;"><span style="font-family: "Courier New", Courier, monospace;">.of</span></span><span style="font-family: 'Courier New', Courier, monospace;">(</span><br />
<div>
<span style="font-family: Arial;"><span style="font-family: "Courier New", Courier, monospace;"> <b><i>(k) -> MyConfigMechanism.get(k)</i></b><br /> </span></span><span style="font-family: Arial;"><span style="color: #38761d; font-family: "Courier New", Courier, monospace;">// String get(String key);</span></span></div>
<div>
<span style="font-family: Arial;"><span style="font-family: "Courier New", Courier, monospace;"> )</span></span></div>
</div>
<div>
<span style="font-family: Arial;"><span style="font-family: "Courier New", Courier, monospace;"> .get("com.mycomp.ratecalculator.rate", <br /> BigDecimal.</span><b><span style="font-family: "Courier New", Courier, monospace;">class</span></b><span style="font-family: "Courier New", Courier, monospace;">))<br /> .orElse(BigDecimal.of(0.05d));</span></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This allows you to support Tamya Configuration, but you can still use your own default configuration logic as default, if Tamaya is not loaded in your target environment.</span></div>
<div>
<br /></div>
<div>
<div>
<br /></div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">What else?</span></h4>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">From an API perspective there is not much more needed. The <span style="font-family: "Courier New", Courier, monospace;">TypeLiteral</span> class used before is the same, which is also known well from Java EE (CDI) and the only other artifact not mentioned is the <span style="font-family: "Courier New", Courier, monospace;">ConfigException</span> class. Of course, this functionality per se is very minimalistic, but it exactly does, what it is supposed to: it provides a <i>minimalistic access API <span style="font-family: Arial, Helvetica, sans-serif;">for configuration</span></i><span style="font-family: Arial, Helvetica, sans-serif;">. And why we think this is so important? Here is why</span></span></div>
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Everybody writing components typically writes some configuration logic, but everybody does it different: different formats, locations, key schemes, overridings etc. Also Apache Tamaya neither wants to define </span><i><span style="font-family: Arial, Helvetica, sans-serif;">what</span></i><span style="font-family: Arial, Helvetica, sans-serif;"> you configure, or </span><i><span style="font-family: Arial, Helvetica, sans-serif;">where</span></i><span style="font-family: Arial, Helvetica, sans-serif;"> your configuration is located and how it can be </span><i><span style="font-family: Arial, Helvetica, sans-serif;">overridden</span></i><span style="font-family: Arial, Helvetica, sans-serif;">. But we define a common API for accessing the configuration. </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Given that components from different teams can be more easily integrated within a project, but also within a concrete enterprise context, since all components refer to the same configuration mechanism.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Even better, when using Tamaya </span><i><span style="font-family: Arial, Helvetica, sans-serif;">overriding</span></i><span style="font-family: Arial, Helvetica, sans-serif;"> rules of configuration can be more or less ignored, since the mechanisms of Tamaya (I will present the corresponding SPI in the next blog here) already provide these mechanisms, so they can be adapted as needed.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Similarly the </span><i><span style="font-family: Arial, Helvetica, sans-serif;">formats</span></i><span style="font-family: Arial, Helvetica, sans-serif;"> used for configuration and also the fact that configuration may be locally stored in the file system or be </span><i><span style="font-family: Arial, Helvetica, sans-serif;">remotely</span></i><span style="font-family: Arial, Helvetica, sans-serif;"> distributed is not of importance anymore.</span></li>
</ol>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This per se should render Apache Tamaya to very interesting and crucial piece of any application or module architecture. Additionally its SPI brings additional benefits, especially within bigger entprise contexts. We will look at the SPI and the extensions in the next blog posts here. So stay tuned!</span></div>
<div>
<span style="font-family: Arial;"><br /></span></div>
<div>
<span style="font-family: Arial;">As always comments are welcome. If anybody out there is also thinking of contributing to the project please get in contact with us under <a href="mailto:dev@tamaya.incbuator.apache.org">dev@tamaya.incubator.apache.org</a>.</span><br />
<span style="font-family: Arial;"><br /></span>
<i><span style="font-family: Trebuchet MS, sans-serif;">And of course, help us spreading words writing tweets, blogs, adopting it, using it, loving it! </span></i><br />
<h4>
<span style="font-family: Arial;">Want to hear more?</span></h4>
<span style="font-family: Arial;">Want to know more about Apache Tamaya? Visit our </span><span style="font-family: Arial, Helvetica, sans-serif;"><a href="http://tamaya.incubator.apache.org/">project site</a></span><span style="font-family: Arial;"> or even better join and see us at </span><br />
<br />
<ul>
<li><a href="http://events.linuxfoundation.org/events/apachecon-core-europe" style="font-family: Arial;">Apache Con Europe 2015 in Budapest</a><span style="font-family: Arial;"> (Anatole Tresch and Werner Keil)</span></li>
<li><a href="http://devoxx.ma/en/" style="font-family: Arial;">DevoXX Marocco</a><span style="font-family: Arial;"> (Werner Keil)</span></li>
</ul>
<br />
<br />
<br />
<span style="font-family: Arial;"><br /></span></div>
</div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com213tag:blogger.com,1999:blog-6710986841844568686.post-217028700692645622014-11-29T02:20:00.000-08:002014-11-29T05:22:09.878-08:00Java Configuration API - Java 7 or Java 8 ?<h2>
Java 7 vs Java 8 for Apache Tamaya Config</h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Since the Apache mailing list is preventing me at all cost my more comprehensive addition to the current Tamaya discussion about Java 7 vs. Java 8, I now decided to write a blog.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">I will shortly show here a small example how a modern configuration API written in Java 8 significantly differs from one written in Java 7 and why it is worth to do it in Java 8, so read ahead:</span><br />
<b id="docs-internal-guid-fb6373a7-fb0b-0ba3-1d62-1597c6176854" style="font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
</div>
<ol>
<li><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 1.15; white-space: pre-wrap;">the target is to build a modern API.</span></li>
<li><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 1.15; white-space: pre-wrap;">there are many developers that do not use Spring or other technologies, where adoption is much faster.</span></li>
<li><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 1.15; white-space: pre-wrap;">Wildfly as well as Weblogic 12.1.3 are Java 8 certified AFAIK (to be verified, since EE7 TCK does not run on Java 8...)</span></li>
<li><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 1.15; white-space: pre-wrap;">Adoption within one year will be great.</span></li>
<li><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 1.15; white-space: pre-wrap;">Java 8 is more than Lambdas and streams!</span></li>
<li><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 1.15; white-space: pre-wrap;">Java 8 is the future! And we design for the future, we do not want to be one additional config framework.</span></li>
<li><span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 1.15; white-space: pre-wrap;">We can still provide a backport for Java 7. The core of Tamaya will be quite small. It should be possible to provide a backport within a couple of hours.</span></li>
</ol>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I give you an example here, e.g. let us start on the </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">PropertyProvider</span><span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: italic; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In Java 8:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public interface</span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> PropertyProvider {</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Optional<String> get(String key);</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> containsKey(String key);</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Map<String, String> toMap();</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> MetaInfo getMetaInfo();</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> hasSameProperties(PropertyProvider provider) {...}</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> keySet(){...}</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> ConfigChangeSet load(){...}</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> isMutable(){...}</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">void</span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> apply(ConfigChangeSet change){...}</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Verdana; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: italic; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In Java 7:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">With Java 7 this would be (to provide similar comfort, but on the cost of implementation dependencies and limited flexibility because of missing behavioural inheritance):</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public interface </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">PropertyProvider {</span></span></div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><b style="font-weight: normal;"><br /></b>
</span><br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Courier New, Courier, monospace; font-size: x-small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> String get(String key); // @throws ConfigException if no value</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Courier New, Courier, monospace; font-size: x-small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> String getOrDefault(String key, String value);</span></div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><b style="font-weight: normal;"><br /></b>
</span><br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> containsKey(String key);</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Courier New, Courier, monospace; font-size: x-small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Map<String, String> toMap();</span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Courier New, Courier, monospace; font-size: x-small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> MetaInfo getMetaInfo();</span></div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><b style="font-weight: normal;"><br /></b>
</span><br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> hasSameProperties(PropertyProvider provider) {...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> keySet(){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> ConfigChangeSet load(){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default boolean </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">isMutable(){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default void </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">apply(ConfigChangeSet change){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Courier New, Courier, monospace; font-size: x-small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}</span></div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><b style="font-weight: normal;"><br /></b>
</span><br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">protected abstract class</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> AbstractPropertyProvider implements PropertyProvider {</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public boolean </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">hasSameProperties(PropertyProvider provider) {...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> keySet(){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> ConfigChangeSet load(){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> isMutable(){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> apply(ConfigChangeSet change){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Courier New, Courier, monospace; font-size: x-small; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">}</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 16px; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Example 2: Configuration</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Looking at </span><span style="background-color: white; color: #222222; font-family: Verdana; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Configuration</span><span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> and the singleton access there things get even worse:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: italic; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In Java 8:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public interface</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Configuration </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">extends</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> PropertyProvider{</span></span></div>
<b style="font-weight: normal;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> <T> Optional<T> get(String key, Class<T> type);</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> addPropertyChangeListener(PropertyChangeListener l);</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> removePropertyChangeListener(PropertyChangeListener l);</span></span></div>
<b style="font-weight: normal;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> OptionalBoolean getBoolean(String key){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> OptionalInt getInteger(String key){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> OptionalLong getLong(String key){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> OptionalDouble getDouble(String key){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> <T> Optional<T> getAdapted(String key, PropertyAdapter<T> adapter){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> getAreas(){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> getTransitiveAreas(){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> getAreas(final Predicate<String> predicate){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> getTransitiveAreas(Predicate<String> predicate){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> containsArea(String key){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Configuration with(ConfigOperator operator){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> <T> T query(ConfigQuery<T> query){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">default</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> String getVersion(){...}</span></span></div>
<b style="font-weight: normal;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> isDefined(String name){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> <T> T of(String name, Class<T> template){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Configuration of(String name){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Configuration of(){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> <T> T of(Class<T> type){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> configure(Object instance){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> public static </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">String evaluateValue(String expression){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> String evaluateValue(Configuration config, String expression){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> addGlobalPropertyChangeListener(PropertyChangeListener listener){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> removeGlobalPropertyChangeListener(PropertyChangeListener listener){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">}</span></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: italic; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In Java 7:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public interface</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Configuration </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">extends</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> PropertyProvider{</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> <T> T get(String key, Class<T> type); // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> <T> T getOrDefault(String key, Class<T> type, T instance);</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> addPropertyChangeListener(PropertyChangeListener l);</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> removePropertyChangeListener(PropertyChangeListener l);</span></span></div>
<b style="font-weight: normal;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getBoolean(String key){... } // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getBooleanOrDefault(String key, boolean defaultVal){... } </span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">int</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getInteger(String key){... } // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">int</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getIntegerOrDefault(String key, int defaultVal){... } </span></span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">long</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getLong(String key){... } // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">long</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getLongOrDefault(String key, long defaultVal);</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">double</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getDouble(String key){... } // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">double</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getDoubleOrDefault(String key, double defaultVal);</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> <T> getAdapted(String key, PropertyAdapter<T> adapter){... } </span></span><br />
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> <T> getAdaptedOrDefault(String key, PropertyAdapter<T> adapter, T defaultVal){... } // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> Set<String> getAreas(){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> Set<String> getTransitiveAreas(){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> Set<String> getAreas(final Predicate<String> predicate){... }</span></span><br />
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> // Duplicate predicate class, or introduce additional interface</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> Set<String> getTransitiveAreas(Predicate<String> predicate){... } </span></span><br />
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> // Duplicate predicate class, or introduce additional interface</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> containsArea(String key){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> Configuration with(ConfigOperator operator){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> <T> T query(ConfigQuery<T> query){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> String getVersion(){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">}</span></span></div>
<b style="font-weight: normal;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public final class</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> ConfigManager{</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">private </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">ConfigManager(){}</span></span></div>
<b style="font-weight: normal;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static boolean </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">isDefined(String name){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> <T> T of(String name, Class<T> template){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Configuration of(String name){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Configuration of(){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> <T> T of(Class<T> type){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> configure(Object instance){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> String evaluateValue(String expression){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> String evaluateValue(Configuration config, String expression)</span></span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> {... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public static</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> addGlobalPropertyChangeListener(</span></span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> PropertyChangeListener listener){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> public static void</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> removeGlobalPropertyChangeListener(</span></span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> PropertyChangeListener listener){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">}</span></span></div>
<b style="font-weight: normal;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">protected abstract class</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> AbstractConfiguration </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">extends</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> AbstractPropertyProvider </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">implements</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Configuration{</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getBoolean(String key){... } // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getBooleanOrDefault(String key, boolean defaultVal){... } </span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">int</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getInteger(String key){... } // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">int</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getIntegerOrDefault(String key, int defaultVal){... } // throws ConfigException if not found</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">long</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getLong(String key){... } // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">long</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getLongOrDefault(String key, long defaultVal);</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">double</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getDouble(String key){... } // throws ConfigExceptio</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">double</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> getDoubleOrDefault(String key, double defaultVal);</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> <T> getAdapted(String key, PropertyAdapter<T> adapter){... } </span></span><br />
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> <T> getAdaptedOrDefault(String key, PropertyAdapter<T> adapter, T defaultVal) </span></span><br />
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> {...} // throws ConfigException</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> getAreas(){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> getTransitiveAreas(){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> getAreas(final Predicate<String> predicate){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Set<String> getTransitiveAreas(Predicate<String> predicate){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> public boolean</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> containsArea(String key){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Configuration with(ConfigOperator operator){... }</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> <T> T query(ConfigQuery<T> query){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">public</span><span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> String getVersion(){...}</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">}</span></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">And even when looking from the </span><span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: italic; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">client side</span><span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: italic; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Java 8:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">String value = Configuration.of().get("a.b.c").orElse(MyClass::calculateDefault);</span></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: italic; font-variant: normal; font-weight: bold; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Java 7:</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">String value = ConfigurationManager.getConfiguration().getOrDefault("a.b.c", null);</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">if(value==null){</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> value = calculateDefault();</span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">}</span></span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">So obviously the strength of Java 8 are far beyond Streams and Lambdas:</span></div>
<ul style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: disc; margin-left: 15px; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The API footprint for clients overall is half the size.</span></div>
</li>
</ul>
<ul style="margin-bottom: 0pt; margin-top: 0pt;">
<li dir="ltr" style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: disc; margin-left: 15px; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The implementations of APIs/SPIs is much more easier and does not introduce implementation dependencies on abstract classes</span></div>
</li>
<li dir="ltr" style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: disc; margin-left: 15px; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Users must known much less artefacts to use the API!</span></div>
</li>
<li dir="ltr" style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: disc; margin-left: 15px; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">It is much more flexible and extendable (eg method references)</span></div>
</li>
<li dir="ltr" style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; list-style-type: disc; margin-left: 15px; text-decoration: none; vertical-align: baseline;"><div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">...</span></div>
</li>
</ul>
<div>
<span style="color: #222222; font-family: Arial;"><span style="font-size: 15px; line-height: 17.25px; white-space: pre-wrap;"><br /></span></span></div>
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The above case with the deferred calculation is additionally a simple but common use case for Lambda usage. Considering implementation use cases like filtering and mapping/combining </span><span style="background-color: white; color: #222222; font-family: Arial; line-height: 1.15; white-space: pre-wrap;">of configuration to other things Streams are incredibly useful as well. Similarly we would loose for sure great support from some of the most communities like SouJava and LJC.</span></div>
<br />
<div dir="ltr" style="line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: white; color: #222222; font-family: Arial; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">So I hope I have now convinced really everybody that it is NOT worth to stick on Java 7, just because we would have faster adoption ;-) ! Do the API right for Java 8 and if enough people ask for do a backport. With the current relative small size of Tamaya a backport should be doable in about 3-4 hours ;)</span><br />
<span style="background-color: white; color: #222222; font-family: Arial; font-style: normal; font-variant: normal; font-weight: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com122tag:blogger.com,1999:blog-6710986841844568686.post-43844948289538644562014-09-28T06:55:00.003-07:002014-09-28T06:57:28.427-07:00Configuration for the Java Platform<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Configuration for the Java Platform</span></h2>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Outcome from the last EC Meeting</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Last week the EC meeting <i>@Twitter</i> HQ discussed a proposal for a new JSR for Configuration targeting application configuration. Since this topic affects not only Java EE, it was proposed as a SE JSR. Discussions were open and constructive. I try to summarize the outcome here:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">One idea was, that we should do an OSS project out of it. I do not think this makes sense, there are already a few of them, all with reasonable maturity. So it should be finally time to standardize how things are configured in the Java eco-system.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Others said we should have a look at what was already done in the ME area. But also after having a look at JSR 36 (CDC 1.0) noch JSR 218 (CDC 1.1), I don't see anything relevant there. Perhaps someone can give me a hint here ;)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Others thought we should create an OpenJDK project. I tend also to disagree with that due to several reasons:</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Developing a JSR that is targeting the JDK directly is much more complicated and my experience from JSR 354 shows that without having Oracle heavily pushing things it might be a high risk to go that way.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">I think community involvement is much easier to achieve doing a "normal" JSR. We can setup a GitHub repo and start working on it. The OpenJDK tool chain is not that easy to use and know how about is not as widely available. Most of all it is much more difficult to get OpenJDK commit rights, than join a OSS project.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">With Jigsaw coming hopefully in Java 9, I expect we get a module system. So it would be pretty easy to add configuration as a Java module once Jigsaw is there. This makes it much more easy again, to focus on the configuration usability aspects and realize Java integration as Jogsaw module later.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">As well waiting for Jigsaw means that no SE JSR can be done for several year. IMO this makes no sense. Nevertheless I agree that the configuration mechanisms proposed must be compatible with Jigsaw.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Finally this JSR tries to focus on application configuration. This also includes relatively early configuration. But we definitively do not want to be part of the Java early loading code. We saw it quite good, how bad design can get and what kind of unwanted side effects can occur, when infrastructure required by low level Java boot processes is messed up with common user functionality. As an example try to load a class using </span><span style="font-family: Courier New, Courier, monospace;">Class.forName(String) </span><span style="font-family: Arial, Helvetica, sans-serif;">during the loading process of the </span><span style="font-family: Courier New, Courier, monospace;">java.util.logging.LogManager </span><span style="font-family: Arial, Helvetica, sans-serif;">(you have to subclass the </span><span style="font-family: Courier New, Courier, monospace;">LogManager </span><span style="font-family: Arial, Helvetica, sans-serif;">and configure it as a system property).</span></li>
</ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Also Redhat, SouJava, LJC, iJUG and others were not seen to be sufficient that we should file the JSR already. There is some probability that it could be voted down, especially, when Oracle is not on board. We definitively have to talk with Oracle people here during Java One!</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Finally feedback was that our JSR proposal should be more precise though no exact details were given, what should be fixed. Nevertheless have a look yourself at XXXX and help us to improve the filing.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So summarizing, adding configuration to the Java eco-system is definitively a Hercules task. OK, it was expected that it will not be easy ;) But good news is, we still we have a chance to get it on track, but we definitively need more support and work to be done. <b>So if you are interested in the topic, write about it, tweet it, advertise it and help to improve our proposal. Communicate your interest, especially to EC members, that we have a unique chance here to improve the overall Java platform and we should not miss it.</b> Especially support by more companies, including Oracle itself, in the EC would be important...</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">As always feedback is welcome and comments will not be restricted, also when you don't agree on my thoughts here.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com7Hilton San Francisco Union Square, 333 O'Farrell Street, San Francisco, Kalifornien 94102, USA37.78539 -122.41137.7838215 -122.4135215 37.7869585 -122.4084785tag:blogger.com,1999:blog-6710986841844568686.post-80254368196406346742014-09-14T07:00:00.002-07:002014-09-14T07:01:36.315-07:00Integrating Configuration with CDI 2.0<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Integrating Configuration with CDI</span></h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Most of you are aware that the original initiative of standardizing of configuration for Java EE deployment aspects was stopped lately. But looking at the topic of configuration we have multiple aspects:</span><br />
<br />
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><b>Deployment configuration</b> in Java EE configuring a deployment into a Java EE server, including things like configuration of EJBs, transactions, datasources, servlets and filters etc. You can basically see this part as a replacement or improvement over the scattered file configurations as of today (web.xml, ejb.jar.xml, ...).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration of aspects that basically are not related to the Java EE platform, but related to the use cases and logic implemented. We call it <b>application configuration</b>. Since dependencies from a configuration mechanism should be minimized, IMO inversion of control is my preferred design concept to be used to "configure" a component, so CDI is the one that matches best.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">If we leave Java EE and imagine our solution built up on Spring, JavaFX, OSGI or other technologies, configuration gets even more generic. In many cases, though the existence of JSR 330, we can not rely on IoC/Dependency Injection to be present, so we need also to provide some kind of SE API, e.g. as outlined in previous blogs here.</span></li>
</ol>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Now given the current situation, I suggest point 1 is not in scope anymore for Java EE 8. Nevertheless there is still much we can do:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Leverage CDI so it is configuration aware</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Standardize configuration as a global and unified concept in a SE JSR.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">In this blog I would like to focus on what would be possible extensions to CDI to support application configuration effectively. </span></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Usage Perspective: Injecting Configured Values</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">As a starting point lets just inject </span><span style="font-family: Courier New, Courier, monospace;">String </span><span style="font-family: Arial, Helvetica, sans-serif;">properties, e.g. as follows</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>public class</b> MyBean {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Configured</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>private </b>String myProperty;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This is the simplest case, it will request for a configuration entry, with the same name as the field, so it looks for </span><span style="font-family: Courier New, Courier, monospace;">"</span><span style="font-family: 'Courier New', Courier, monospace;">myProperty</span><span style="font-family: Courier New, Courier, monospace;">"</span><span style="font-family: Arial, Helvetica, sans-serif;">. Now in many cases we probably want to have a different configuration key to be used for the lookup:</span></div>
<br />
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> @Configured("com.apple.myconfig.myProperty")</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private </b>String myProperty;</span></div>
<div>
<br /></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Now what should happen, if configuration is not present? I suggest, without any <i>default</i> value, it should be managed like a deployment error. So we also want to be able to pass a default value here:</span></div>
<br />
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Configured(value="com.apple.myconfig.myProperty", <br /> defaultValue="256")</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private </b>String myProperty;</span></div>
</div>
<br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Obviously the configured value above is a number. So I would expect the runtime system is capable of injecting it also as number:</span></div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> @Configured(value="com.apple.myconfig.myProperty",</span><span style="font-family: 'Courier New', Courier, monospace;"> </span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> defaultValue="256")</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private int </b>myProperty;</span></div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Fine so far. Looking at Spring and other frameworks, you may also want to configure more complex things, e.g. injecting a </span><span style="font-family: Courier New, Courier, monospace;">Collection </span><span style="font-family: Arial, Helvetica, sans-serif;">type:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> @Configured(value="com.apple.myconfig.myList",</span><span style="font-family: 'Courier New', Courier, monospace;"> </span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> defaultValue="['a','b','c']")</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private </b>List<String> MyList;</span></div>
</div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Since configuration is basically data added to a system externally it must also be validatable, so we could add bean validation annotations on it:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> @Configured(value="com.apple.myconfig.myProperty",</span><span style="font-family: 'Courier New', Courier, monospace;"> </span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> defaultValue="256")</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Min(5)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Max(200)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private int </b>myProperty;</span></div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically looking at the code above it looks quite the same as what you can do with CDI already as of now. This makes sens since basically you simply do nothing different than injecting values. Similarly you want to separate different configurations in a system, may by qualifying them:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> @Configured(value="com.apple.myconfig.myProperty",</span><span style="font-family: 'Courier New', Courier, monospace;"> </span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> defaultValue="256")</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @SystemConfig // Qualifier annotation</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private int </b>myProperty</span></div>
</div>
</div>
<div>
<div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif; font-weight: normal;">Finally default values also could support EL expressions:</span></h4>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> @Configured(value="com.myComp.stage",</span><span style="font-family: 'Courier New', Courier, monospace;"> </span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> defaultValue="${environment.stage")</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @NotNull</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private </b>Stage stage</span></div>
</div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif; font-weight: normal;"><br /></span></div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Advanced Use Cases</span></h4>
</div>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Multiple Configuration Keys</i></span><br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">In some cases there is a need to read out information from <i>several </i>configuration locations, hereby defining an order of precedence between several keys. That can be easily achieved by allowing an array of configuration keys to be defined within the annotation:</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<b style="font-family: 'Courier New', Courier, monospace;"> public class</b><span style="font-family: 'Courier New', Courier, monospace;"> MyBean {</span></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> @Configured("myProperty", my.myconfig.myProperty"</span><span style="font-family: 'Courier New', Courier, monospace;">)</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private int </b>myProperty</span></div>
</div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Configuration Root Keys</i></span><br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">When organizing configuration in a hierarchical tree, a component typically reads several keys out of one sub-path, often called configuration <i>area</i>. Instead of having to retype the area all the time (which is error prone), it can be added as a default on class level, so the following example would lookup configuration with keys </span><span style="font-family: Courier New, Courier, monospace;">a.b.c.myProperty, a.b.c.num</span><span style="font-family: Arial, Helvetica, sans-serif;">:</span></div>
</div>
<div>
<br /></div>
<div>
<b> <span style="font-family: 'Courier New', Courier, monospace;">@ConfigArea("a.b.c")</span></b></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public class</b><span style="font-family: 'Courier New', Courier, monospace;"> MyBean {</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> @Configured</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private int </b>myProperty;</span></div>
</div>
</div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> @Configured("num")</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private int </b>myProperty2;</span></div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Configuration Filtering</i></span></div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Similarly you want to add sometimes a filter (operator) converting the configured </span><span style="font-family: Courier New, Courier, monospace;">String </span><span style="font-family: Arial, Helvetica, sans-serif;">value to another </span><span style="font-family: 'Courier New', Courier, monospace;">String </span><span style="font-family: Arial, Helvetica, sans-serif;">value (e.g. decrypting an encrypted password):</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> @ConfiguredProperty(value={"users.admin.myPwd"}, </span><span style="font-family: 'Courier New', Courier, monospace;"> filter=foo.bar.MyPwdConverter.<b>class</b>)</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private </b>String password;</span></div>
</div>
</div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Custom Adapter</i></span></div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Or you want to override/provide the <i>converter to be used for type conversion</i> from </span><span style="font-family: 'Courier New', Courier, monospace;">String </span><span style="font-family: Arial, Helvetica, sans-serif;">to the required target type:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> @Configuredured(value={"users.admin.myAmount"}, </span><span style="font-family: 'Courier New', Courier, monospace;"> converter=foo.bar.MyAmountConverter.<b>class</b>)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> private </b>MonetaryAmount amount;</span></div>
</div>
</div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif; font-weight: normal;"><i>Listening to Configuration Changes</i></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Several times we want to be aware if configuration values change. Basically we could simply listen for </span><span style="font-family: Courier New, Courier, monospace;">PropertyChangeEvent </span><span style="font-family: Arial, Helvetica, sans-serif;">instances: </span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>public class</b> MyBean {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Configured</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>private </b>String myProperty;</span></div>
<br />
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> /**</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> * Event sent, whenever a configured property is</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> * changed (reinjected).<br /> * @param evt the event describing the changed property<br /> */</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>void </b>configChanged(@ConfigChange PropertyChangeEvent evt){</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This would allow to get informed on configuration changes easily, but would not imply any internal know how, how configuration is managed.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Alternate: Constraint Injected Types to simple Type only</span></h4>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The above though clearly separated has a couple of intersection with CDI. So it might be an option to reduce the configurable types to only the following:</span></div>
</div>
<div>
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;">All primitive types such as </span><span style="font-family: Courier New, Courier, monospace;">boolean, byte, char, short, int, long, float, double</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The corresponding wrapper types such as </span><span style="font-family: Courier New, Courier, monospace;">Boolean, Character, Byte, Short, Integer, Long, Float, Double</span><span style="font-family: Arial, Helvetica, sans-serif;">, but also </span><span style="font-family: Courier New, Courier, monospace;">Number</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Additionally: </span><span style="font-family: Courier New, Courier, monospace;">String, BigDecimal, BigInteger</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
</ol>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This would result in a fairly simple configuration mechanism. Additional features can then be added on top of that using CDI mechanisms, e.g. factory or producer classes that provide corresponding more complex instances that can be injected in other places:</span></div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>public class </b>NameListProvider{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Configured</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>private </b>String configuredList;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Produces @NamedList @Dependent<br /> <b>public </b>List<String> getNamedList(){</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> List<String> result = <b>new </b>ArrayList<>();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> parseList(result);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> return result;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>private void </b>parseList(List<String> list){ ... }</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">A possible disadvantage of this solution is that the conversions are not inherently reusable and therefore similar conversions may be duplicated multiple times on a system. </span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">CDI Perspective: How can configuration features be realized</span></h3>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Basic Mechanism</span></h4>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">As a starting point let us elaborate the runtime requirements configured beans/properties should have. I would suggest something like the following:</span></div>
</div>
<div>
<ol>
<li><span style="font-family: Courier New, Courier, monospace;">Configured </span><span style="font-family: Arial, Helvetica, sans-serif;">properties are based on </span><span style="font-family: Courier New, Courier, monospace;">String </span><span style="font-family: Arial, Helvetica, sans-serif;">values only and managed by the configuration system only and not related to CDI.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">They can be <i>converted </i>to any non <span style="font-family: 'Courier New', Courier, monospace;">String </span>based type, but conversion will be performed by the configuration subsystem. Especially configured objects do not support injection of any dependencies.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configured properties can be qualified. </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-family: 'Courier New', Courier, monospace;">Configured </span>values are<i> injected during the initialization</i> of the CDI bean. It is the responsibility of the configuration system to determine the correct value, e.g. depenending on the current runtime context, or whatever is required to determine the correct configured value. The CDI container only provides the glue mechanism so configuration can be injected at the right locations.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Any configured values are <i>always injected with</i> </span><span style="font-family: Courier New, Courier, monospace;">@Dependent</span><span style="font-family: Arial, Helvetica, sans-serif;"> <i>scope</i>. Adding any other scope annotation is handled as a deployment error.</span></li>
</ol>
</div>
<div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Realization Variants</span></h4>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">When we look at the possible implementation requirements and the possible way, how this can be implemented using CDI, there are different possible options, how concerns can be separated between CDI and a configuration subsystem:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Extending CDI</i></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">In this scenario CDI would be extended. meaning, that CDI itself defines the required annotations such as </span><span style="font-family: Courier New, Courier, monospace;">@Configured, @ConfigChange</span><span style="font-family: Arial, Helvetica, sans-serif;"> and also provides an SPI interface that can be registered (e.g. with </span><span style="font-family: Courier New, Courier, monospace;">java.util.ServiceLoader</span><span style="font-family: Arial, Helvetica, sans-serif;">) for accessing configuration values. </span><span style="font-family: Arial, Helvetica, sans-serif;">One important key aspect is that CDI should not know how configuration is managed. Basically configuration can be as simple as a </span><span style="font-family: Courier New, Courier, monospace;">.properties</span><span style="font-family: Arial, Helvetica, sans-serif;"> file in the classpath. In other cases it may be multilayered, dynamic system that even may run external to the current VM. So we need some very general abstraction to decouple CDI from this complexities. A minimalistic variant of such an SPI interface could look as follows:</span></div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> public interface</b> ConfigAccessor{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <T> T getConfiguredValue(Field f, Object instance,<br /> Class<T> type,<br /> Annotation... qualifiers,</span><br />
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">ConfigChangeListener l</span><span style="font-family: 'Courier New', Courier, monospace;">);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <b>void </b>addConfigChangeListener(ConfigChangeListener l);</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><b> void </b>remove</span><span style="font-family: 'Courier New', Courier, monospace;">ConfigChangeListener(ConfigChangeListener l);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
</div>
</div>
<div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Nevertheless this variant would have significant drawbacks:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It is questionable, if such an SPI should really be part of CDI.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Also CDI would probably not bring a configuration implementation with it (or only a very minimalistic one). </span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">An advantage of doing so, would be that the basic mapping between configuration and the CDI injection mechanisms is well defined. Nevertheless let's further see if we have other options.</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Generalizing Producers</i></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Looking at the examples we could also think about if the mechanisms shown could be generalized. </span><span style="font-family: Arial, Helvetica, sans-serif;">Basically configuration injection is similar to satisfying dependencies using an external bean provider. Basically this what <i>producers </i>are built for. So basically we could also let CDI to the injection work...</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b> public class</b> MyBean {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Inject @Configured</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>private </b>String myProperty;</span></div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">...and </span><span style="font-family: Arial, Helvetica, sans-serif;">add an according producer bean for injecting configuration and hereby defining </span><span style="font-family: Courier New, Courier, monospace;">@Configured</span><span style="font-family: Arial, Helvetica, sans-serif;"> as CDI qualifier:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div>
<span style="font-family: Courier New, Courier, monospace;"> @ApplicationScoped</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public class </b><span style="font-family: 'Courier New', Courier, monospace;">ConfigProducer{</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"> @Produces </span><span style="font-family: 'Courier New', Courier, monospace;">@Configured</span><span style="font-family: Courier New, Courier, monospace;"> @Dependent</span></div>
</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"> <b>public </b>String getStringConfig(){...}</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">@Produces </span><span style="font-family: 'Courier New', Courier, monospace;">@Configured</span><span style="font-family: 'Courier New', Courier, monospace;"> @Dependent</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"> <b>public </b>Integer getStringConfig(){...}</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">@Produces </span><span style="font-family: 'Courier New', Courier, monospace;">@Configured</span><span style="font-family: 'Courier New', Courier, monospace;"> @Dependent</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public </b><span style="font-family: 'Courier New', Courier, monospace;">Boolean getStringConfig(){...}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">}</span></div>
<div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Nevertheless, if we could define that a producer will provide instances for any kind of injection targets with a certain qualifier, this would definitively allow us to inject all kind of configured values. </span><span style="font-family: Arial, Helvetica, sans-serif;">To achieve this I added an additional flag (</span><span style="font-family: 'Courier New', Courier, monospace;">ProducerType)</span><span style="font-family: Arial, Helvetica, sans-serif;"> to the </span><span style="font-family: Courier New, Courier, monospace;">@Produces</span><span style="font-family: Arial, Helvetica, sans-serif;"> annotation to tell the CDI container that this producer should be used to delegate object production to any kind of target types qualified with </span><span style="font-family: Courier New, Courier, monospace;">@Configured</span><span style="font-family: Arial, Helvetica, sans-serif;"> :</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @ApplicationScoped</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;">public class </b><span style="font-family: 'Courier New', Courier, monospace;">ConfigProducer{</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">@Produces(<b>ProducerType.ALL</b>) </span><span style="font-family: 'Courier New', Courier, monospace;">@Configured</span><span style="font-family: 'Courier New', Courier, monospace;"> @Dependent</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"> <b>public </b>Object getConfiguredValue(InjectionTarget<?> tgt){...}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Clearly also this variant has drawbacks: </span><br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It is not type-safe.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Producers may easily have intersections with other producers and more easily lead to deployment errors.</span></li>
</ul>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Using Portable Extensions</i></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Finally simply implementing a portable extension is not only enough, it provides also the most portable and powerful mechanism. Even the current CDI 1.1 is fully sufficient to implement a configuration feature seamlessly</span><span style="font-family: Arial, Helvetica, sans-serif;">:</span></div>
</div>
<div>
<div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The extension listens to the </span><span style="font-family: Courier New, Courier, monospace;">ProcessInjectionTarget </span><span style="font-family: Arial, Helvetica, sans-serif;">event. This will be called for every bean.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The extension could then check for </span><span style="font-family: Courier New, Courier, monospace;">@Configured</span><span style="font-family: Arial, Helvetica, sans-serif;"> (or </span><span style="font-family: Courier New, Courier, monospace;">@ConfigChange)</span><span style="font-family: Arial, Helvetica, sans-serif;"> annotations and could adapt the </span><span style="font-family: Courier New, Courier, monospace;">InjectionTarget</span><span style="font-family: Arial, Helvetica, sans-serif;">, so it can intercept the injection process, when the bean is initalized. This allows to populate the bean created with the configuration values as needed (as dependent scope).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Similarly the extension manages the injected beans (using weak r</span><span style="font-family: Arial, Helvetica, sans-serif;">eferences), which want to listen for configuration changes. Similarly if the underlying configuration changes, it can reinject the according properties and call according methods on the bean annotated with </span><span style="font-family: Courier New, Courier, monospace;">@ConfigChange</span><span style="font-family: Arial, Helvetica, sans-serif;"> to inform the bean about the configuration change.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">If the configuration subsystem wants to publish further CDI events should be solely in the responsibility of the configuration system used.</span></li>
</ul>
</div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">As an additional advantage also CDI itself could be configured using the same extension mechanism (see below).</span><br />
<br /></div>
</div>
<div>
<ul>
</ul>
</div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Configuring CDI</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Going down the layers CDI itself should be made externally configurable. Hereby one may say we already have </span><span style="font-family: Courier New, Courier, monospace;">beans.xml</span><span style="font-family: Arial, Helvetica, sans-serif;"> and annotations. The problem is that both of these concepts are bound to <i>compile or package time mechanisms</i>. A bundled <i>ear </i>or <i>war </i>archive cannot be changed without opening it, changing it and recreating it with changes included. But this is a thing configuration exactly wants to prevent. Configuration therefore may be provided in a way and with mechanisms that is not controlled by the component to be configured. As a consequence we need a dynamic way for connecting configuration logic with the CDI subsystem that is capable of</span></div>
</div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">be available and accessible during deployment/initialization time of the CDI container.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">be dynamic, so depending on the current valid configuration for a given setup the right values are returned.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically this can be achieved most easily by an service provider interface (SPI) defined by CDI. E.g. CDI could add a </span><span style="font-family: Courier New, Courier, monospace;">CDIConfiguration </span><span style="font-family: Arial, Helvetica, sans-serif;">interface as illustrated below that can be configured using the </span><span style="font-family: Courier New, Courier, monospace;">java.util.ServiceLoader</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>public interface </b>CDIConfiguration{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">Collection<</span><span style="font-family: 'Courier New', Courier, monospace;">Class<? extends Extension></span><span style="font-family: 'Courier New', Courier, monospace;">> getExtensions</span><span style="font-family: 'Courier New', Courier, monospace;">();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">Collection<</span><span style="font-family: 'Courier New', Courier, monospace;">Class<?></span><span style="font-family: 'Courier New', Courier, monospace;">> getAlternative</span><span style="font-family: 'Courier New', Courier, monospace;">Bean</span><span style="font-family: 'Courier New', Courier, monospace;">s();</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">Collection</span><span style="font-family: 'Courier New', Courier, monospace;"><</span><span style="font-family: 'Courier New', Courier, monospace;">Class<?></span><span style="font-family: 'Courier New', Courier, monospace;">> getAlternative</span><span style="font-family: 'Courier New', Courier, monospace;">Stereotype</span><span style="font-family: 'Courier New', Courier, monospace;">s();</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> List<Class<?>> getInterceptors();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> List<Class<?>> getDecorators();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;">Collection</span><span style="font-family: Courier New, Courier, monospace;"><String> getScanExcludes();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The problem with this proposal is that adding/enabling things is easy, but disabling things is more complex. <b>But wait! Fortunately CDI comes with a much more powerful concept: CDI extensions</b>, which gives you full access for modifying the CDI metamodel. With that we can</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Register beans or d</span><span style="font-family: Arial, Helvetica, sans-serif;">eadactivate (veto) beans and alternatives.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Add, Adapt, Remove injection points</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Adding or removing interceptors, decorators.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Add/remove interceptors, decorators on individual beans</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">...</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So basically CDI extensions already enables us to control CDI. The only thing missing is to define a configuration model, that reflects the different things we want to made configurable. Since we are using a simple </span><span style="font-family: Courier New, Courier, monospace;">Map<String,String></span><span style="font-family: Arial, Helvetica, sans-serif;"> based model, we could e.g. define the following:</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">// Adding/defining things</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.alternativeClasses=class1,class2,class3</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.alternativeStereotypes=class1,class2,class3</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.interceptors=class1,class2,class3</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.decorators=class1,class2,class3</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans=class1,class2,class3</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.scanExcludes=path1;path2</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">javax.enterpise.inject.extensions=class1,class2,class3</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">// Removing/deactivating things</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.alternativeClasses.vetoed=class1,class2,class3</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.alternativeStereotypes.vetoed=class1,class2,class3</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.interceptors.vetoed=class1,class2,class3</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.decorators.vetoed=class1,class2,class3</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.vetoed=class1,class2,class3</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.beans.scanExcludes.vetoed=path1;path2</span></div>
</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">javax.enterpise.inject.extensions.vetoed=class1,class2,class3</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This configuration basically would enable to configure everything you can do with </span><span style="font-family: Courier New, Courier, monospace;">beans.xml</span><span style="font-family: Arial, Helvetica, sans-serif;">. But we can also think of additional features, e.g.:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">// Adding interceptors to a bean</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.bean:myBeanClass.intercetors=</span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">class1</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">// Adding interceptors to a method on a bean</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.bean:myBeanClass#myMethodName(class).intercetors=</span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">class1</span></div>
</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">// Remove an interceptors from a bean</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.bean:myBeanClass.intercetors.vetoed=</span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">class1</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">// </span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Remove</span><span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> an interceptor from a method on a bean</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">javax.enterpise.inject.bean:myBeanClass#myMethodName(class).intercetors</span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">.vetoed</span><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">=</span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">class1</span></div>
</div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">...</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Outlook</span></h3>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The most important outcome for me is that adding application configuration support to CDI does not require CDI to be adapted in any way. CDI already as of now is flexible enough so it can fully support configuration injection, including advanced use cases. This is basically a consequence of the very powerful SPI provided by CDI that allows to adapt the metamodel in a very flexible way. Unfortunately, given the EE configuration initiative seems to be stuck there is only little probability that also all other EE JSRs follow this example and provide similar SPIs, so they can be easily configured without the deployment of xml deployment descriptors. Nevertheless if they do (or would be accordingly enhanced during EE8 work, we could add configuration support in wide areas nevertheless.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">As a consequence a standardization initiative as SE standalone JSR would probably be a good variant for starting defining configuration aspects in Java and therefore make corresponding code more interoperable. Such a SE JSR could start very small in a first release, so it could be finished as well within the EE8 timeline. That would enable applications not only to benefit from EE8 in a couple of years, but also having a configuration mechanism in place that is powerful enough to cover many of the aspects in daily live, except those of deployment configuration of the application servers. Such </span><span style="font-family: Arial, Helvetica, sans-serif;">a JSR could define a simple APIs covering the following</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">an API that models configuration and the current runtime environment (</span><span style="font-family: Courier New, Courier, monospace;">util.preferences</span><span style="font-family: Arial, Helvetica, sans-serif;"> is not sufficient!)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">listeners for listening to config changes</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">accessors to access configuration</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">utilities to work buildup configurations</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">optionally also adapting of Strings to objects</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">some functional extension points (operators, queries)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">an SE based SPI</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Such a configuration implementation then could be easily hooked into CDI and all other JSRs as they provide configurable meta-models. thus covering most of the configuration requirements.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">More advanced concepts like configuration meta-modelling, building configurations from multiple trees, merging, filtering, security, views and templates would probably be postponed to a later version of such a spec. Nevertheless the reference implementation could provide some of these features, even as pluggable modules, and best practice will show, which of them will qualify to be further standardized at a later point.</span></div>
</div>
</div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Everybody is welcome to comment on this blog. Especially comments and ideas on how specification of configuration aspects should evolve would be very useful.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com9tag:blogger.com,1999:blog-6710986841844568686.post-49953542917369330652014-09-03T14:40:00.001-07:002014-09-03T14:41:24.195-07:00No Java EE Configuration JSR for EE 8<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">No Java EE Configuration for EE8</span></h2>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;">Dear all</span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;">I apologize to have really disappointing news about the configuration JSR. Though we had basically setup everything, and I was really working hard to get the config JSR up and running, no suitable agreement on the long term support for the TCK/RI could finally be found. Also my last trials to find alternative ways/partners was not successful. Since Credit Suisse is not able/willing to lead such an important JSR on its own, I must inform you that, if not something significant happens, there will be NO CONFIGURATION JSR. </span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;">I am personally very disappointed on that and also think that a good chance to improve our Java EE eco-system will be missed.</span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;">I will still try to push forward the topic, but since my current employer does not support OSS projects outside of the JCP, I will not be able to contribute any code in the next time.</span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;">If you have any questions you still may get in contact with me, or talk to me at JavaOne.</span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;">Cheers,</span></div>
<div class="gmail_default" style="background-color: white; color: #222222; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;">Anatole</span></div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com255tag:blogger.com,1999:blog-6710986841844568686.post-62641815059397092972014-08-26T08:05:00.002-07:002014-10-09T12:37:55.108-07:00Existing Configuration Solutions<h2>
Existing Application Configuration Solutions</h2>
<h3>
<span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; font-weight: normal; line-height: 19.5px;">Within this blog I try to give some details on existing common configuration mechanisms in place. If I miss something, let me know, so I can add it here. Also not that the ordering of the section in this blog is completely random, it does not reflect any valuation from my side.</span></h3>
<div>
<span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; font-weight: normal; line-height: 19.5px;">Also I explicitly do not focus on deployment configuration such as EJB deployment descriptors, CDI beans configuration, resource configuration, configuration for JPA, Bean Validation, web applications etc. This may be covered in another blog.</span></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">1. Play Framework</span></h3>
<span style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 12px; line-height: 16.799999237060547px; text-align: justify;">See <a href="http://www.playframework.com/documentation/2.0/Configuration">http://www.playframework.com/documentation/2.0/Configuration</a></span><br />
<span style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 12px; line-height: 16.799999237060547px; text-align: justify;"><br /></span>
<span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; line-height: 19.5px;">The default configuration file of a Play 2.0 application must be defined in</span><code style="background-color: #fafafa; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #666666; font-family: inconsolata, monospace; font-size: 15px; height: 4px; line-height: 19.5px; margin: 0px; outline: 0px; padding: 0px;">conf/application.conf</code><span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; line-height: 19.5px;">. It uses the HOCON format ( “Human-Optimized Config Object Notation”).</span><br />
<span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; line-height: 19.5px;"><br /></span>
<span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; line-height: 19.5px;">These system properties specify a replacement for </span><code style="background-color: #fafafa; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #666666; font-family: inconsolata, monospace; font-size: 15px; height: 4px; line-height: 19.5px; margin: 0px; outline: 0px; padding: 0px;">application.conf</code><span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; line-height: 19.5px;">. 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.</span><br />
<h4>
<span style="background-color: white; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 19.5px;">HOCON Syntax</span></h4>
<span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; line-height: 19.5px;">Its basically a simplified JSON-Format with some changes, but not compatible with pure JSON.</span><br />
<ul>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">Comments, with <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">#</code> or <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">//</code></span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">Allow omitting the <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">{}</code> around a root object</span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">Allow <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">=</code> as a synonym for <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">:</code></span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">Allow omitting the <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">=</code> or <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">:</code> before a <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">{</code> so <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">foo { a : 42 }</code></span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">Allow omitting commas as long as there's a newline</span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">Allow trailing commas after last element in objects and arrays</span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">Allow unquoted strings for keys and values</span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">Unquoted keys can use dot-notation for nested objects, <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">foo.bar=42</code> means <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">foo { bar : 42 }</code></span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">Duplicate keys are allowed; later values override earlier, except for object-valued keys where the two objects are merged recursively</span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;"><code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">include</code> feature merges root object in another file into current object, so <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">foo { include "bar.json" }</code>merges keys in <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">bar.json</code> into the object <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">foo</code></span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">include with no file extension includes any of <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">.conf</code>, <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">.json</code>, <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">.properties</code></span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">you can include files, URLs, or classpath resources; use <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">include url("http://example.com")</code> or <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">file()</code>or <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">classpath()</code> syntax to force the type, or use just <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">include "whatever"</code> to have the library do what you probably mean (Note: <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">url()</code>/<code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">file()</code>/<code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">classpath()</code> syntax is not supported in Play/Akka 2.0, only in later releases.)</span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">substitutions <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">foo : ${a.b}</code> sets key <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">foo</code> to the same value as the <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">b</code> field in the <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">a</code> object</span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">substitutions concatenate into unquoted strings, <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">foo : the quick ${colors.fox} jumped</code></span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">substitutions fall back to environment variables if they don't resolve in the config itself, so <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">${HOME}</code> would work as you expect. Also, most configs have system properties merged in so you could use <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">${user.home}</code>.</span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">substitutions normally cause an error if unresolved, but there is a syntax <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">${?a.b}</code> to permit them to be missing.</span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;"><code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">+=</code> syntax to append elements to arrays, <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-size: 12px; margin: 0px; padding: 0px;">path += "/bin"</code></span></li>
<li style="box-sizing: border-box;"><span style="font-family: Arial, Helvetica, sans-serif;">multi-line strings with triple quotes as in Python or Scala</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Examples:</span></div>
<div>
<pre style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;"><code style="background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; box-sizing: border-box; display: inline; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: inherit; margin: 0px; padding: 0px; word-wrap: normal;">foo {
bar = 10
baz = 12
}</code></pre>
<pre style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;"><code style="background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; box-sizing: border-box; display: inline; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: inherit; margin: 0px; padding: 0px; word-wrap: normal;">foo.bar=10
foo.baz=12</code></pre>
</div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">2. Typesafe Config Library</span></h3>
</div>
<div>
See <a href="https://github.com/typesafehub/config">https://github.com/typesafehub/config</a></div>
<div>
<ul style="box-sizing: border-box; color: #333333; font-size: 15px; line-height: 25.5px; margin: 15px 0px; padding: 0px 0px 0px 30px;">
<li style="font-family: Helvetica, arial, freesans, clean, sans-serif;"><span style="background-color: white;">Formats supported: Java properties, JSON, and a human-friendly JSON superset.</span></li>
<li style="box-sizing: border-box; font-family: Helvetica, arial, freesans, clean, sans-serif;">merges multiple files across all formats</li>
<li style="box-sizing: border-box; font-family: Helvetica, arial, freesans, clean, sans-serif;">can load from files, URLs, or classpath</li>
<li style="box-sizing: border-box; font-family: Helvetica, arial, freesans, clean, sans-serif;"><span style="background-color: white;">users can override the config with Java system properties</span></li>
<li style="box-sizing: border-box;"><span style="background-color: white;"><span style="font-family: Helvetica, arial, freesans, clean, sans-serif;">converts types, so if you ask for a boolean and the value is the string </span><span style="font-family: Courier New, Courier, monospace;">"yes"</span><span style="font-family: Helvetica, arial, freesans, clean, sans-serif;">, or you ask for a float and the value is an int, it will figure it out</span></span></li>
<li style="box-sizing: border-box; font-family: Helvetica, arial, freesans, clean, sans-serif;"><span style="background-color: white;">Supports substitutions</span></li>
<li style="box-sizing: border-box; font-family: Helvetica, arial, freesans, clean, sans-serif;">API based on immutable <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">Config</code> instances, for thread safety and easy reasoning about config transformations</li>
<li style="box-sizing: border-box; font-family: Helvetica, arial, freesans, clean, sans-serif;">API Example</li>
</ul>
<div>
<pre style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;"><code style="background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; box-sizing: border-box; display: inline; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: inherit; margin: 0px; padding: 0px; word-wrap: normal;">Config conf = ConfigFactory.load();
int bar1 = conf.getInt("foo.bar");
Config foo = conf.getConfig("foo");
int bar2 = foo.getInt("bar");</code></pre>
</div>
<div>
<div style="box-sizing: border-box; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25.5px; margin-bottom: 15px; margin-top: 15px;">
The convenience method <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">ConfigFactory.load()</code> loads the following (first-listed are higher priority):</div>
<ul style="box-sizing: border-box; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25.5px; margin: 15px 0px; padding: 0px 0px 0px 30px;">
<li style="box-sizing: border-box;">system properties</li>
<li style="box-sizing: border-box;"><code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">application.conf</code> (all resources on classpath with this name)</li>
<li style="box-sizing: border-box;"><code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">application.json</code> (all resources on classpath with this name)</li>
<li style="box-sizing: border-box;"><code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">application.properties</code> (all resources on classpath with this name)</li>
<li style="box-sizing: border-box;"><code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">reference.conf</code> (all resources on classpath with this name)</li>
</ul>
<div style="box-sizing: border-box; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25.5px; margin-bottom: 15px; margin-top: 15px;">
The idea is that libraries and frameworks should ship with a <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">reference.conf</code> in their jar. Applications should provide an <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">application.conf</code>, or if they want to create multiple configurations in a single JVM, they could use<code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">ConfigFactory.load("myapp")</code> to load their own <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">myapp.conf</code>. (Applications <em style="box-sizing: border-box;">can</em> provide a <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">reference.conf</code> also if they want, but you may not find it necessary to separate it from <code style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin: 0px; padding: 0px;">application.conf</code>.)</div>
<div style="box-sizing: border-box; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; font-size: 15px; line-height: 25.5px; margin-bottom: 15px; margin-top: 15px;">
Finally it supports configuration merging based on so called <i>fallbacks</i>:</div>
<pre style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(221, 221, 221); box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 13px; line-height: 19px; margin-bottom: 15px; margin-top: 15px; overflow: auto; padding: 6px 10px; word-wrap: normal;"><code style="background-color: transparent; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: none; box-sizing: border-box; display: inline; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: inherit; margin: 0px; padding: 0px; word-wrap: normal;">Config devConfig = originalConfig
.getConfig("dev")
.withFallback(originalConfig)</code></pre>
</div>
</div>
<div>
<br /></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">3. Spring</span></h3>
<div>
See <a href="http://docs.spring.io/spring-boot/docs/1.0.2.RELEASE/reference/htmlsingle/#using-boot-configuration-classes">http://docs.spring.io/spring-boot/docs/1.0.2.RELEASE/reference/htmlsingle/#using-boot-configuration-classes</a></div>
<div>
<br /></div>
<div>
<div style="color: #333333; font-family: Helvetica, Arial, Freesans, Clean, sans-serif; line-height: 25.600000381469727px; margin-bottom: 15px;">
Spring Boot allows you to externalize your configuration so you can work with the same application code in different environments. You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration. Property values can be injected directly into your beans using the <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">@Value</code> annotation, accessed via Spring’s <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">Environment</code> abstraction or bound to structured objects.</div>
<div style="color: #333333; font-family: Helvetica, Arial, Freesans, Clean, sans-serif; line-height: 25.600000381469727px; margin-bottom: 15px; margin-top: 15px;">
Spring Boot uses a very particular <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">PropertySource</code> order that is designed to allow sensible overriding of values, properties are considered in the the following order:</div>
<div class="orderedlist" style="color: #333333; font-family: Helvetica, Arial, Freesans, Clean, sans-serif; line-height: 25.600000381469727px; margin: 0pt;">
<ol class="orderedlist" style="padding-left: 30px;" type="1">
<li class="listitem">Command line arguments.</li>
<li class="listitem">Java System properties (<code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">System.getProperties()</code>).</li>
<li class="listitem">OS environment variables.</li>
<li class="listitem">A <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">RandomValuePropertySource</code> that only has properties in <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">random.*</code>.</li>
<li class="listitem"><code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">@PropertySource</code> annotations on your <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">@Configuration</code> classes.</li>
<li class="listitem">Application properties outside of your packaged jar (<code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">application.properties</code> including YAML and profile variants).</li>
<li class="listitem">Application properties packaged inside your jar (<code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">application.properties</code> including YAML and profile variants).</li>
<li class="listitem">Default properties (specified using <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">SpringApplication.setDefaultProperties</code>).</li>
</ol>
</div>
</div>
<div>
<div style="color: #333333; font-family: Helvetica, Arial, Freesans, Clean, sans-serif; line-height: 25.600000381469727px; margin-bottom: 15px;">
<code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">SpringApplication</code> will load properties from <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">application.properties</code> files in the following locations and add them to the Spring <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">Environment</code>:</div>
<div class="orderedlist" style="color: #333333; font-family: Helvetica, Arial, Freesans, Clean, sans-serif; line-height: 25.600000381469727px; margin: 0pt;">
<ol class="orderedlist" style="padding-left: 30px;" type="1">
<li class="listitem">A <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">/config</code> subdir of the current directory.</li>
<li class="listitem">The current directory</li>
<li class="listitem">A classpath <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">/config</code> package</li>
<li class="listitem">The classpath root</li>
</ol>
<div>
In addition to <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">application.properties</code> files, profile specific properties can also be defined using the naming convention <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">application-{profile}.properties</code>.</div>
<div>
<br /></div>
<div>
<div style="margin-bottom: 15px;">
The values in <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">application.properties</code> are filtered through the existing <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">Environment</code> when they are used so you can refer back to previously defined values (e.g. from System properties).</div>
<pre class="programlisting" style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); clear: both; color: black; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 15px; line-height: 1.4; overflow: auto; padding: 6px 10px;"><span class="hl-attribute" style="color: #7f007f;">app.name</span>=MyApp
<span class="hl-attribute" style="color: #7f007f;">app.description</span>=${app.name} is a Spring Boot application</pre>
<pre class="programlisting" style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); clear: both; color: black; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 15px; line-height: 1.4; overflow: auto; padding: 6px 10px;"><pre class="programlisting" style="border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); clear: both; font-family: Consolas, 'Liberation Mono', Courier, monospace; line-height: 1.4; overflow: auto; padding: 6px 10px;"><span class="hl-attribute" style="color: #7f007f;">dev</span>:
<span class="hl-attribute" style="color: #7f007f;"> url</span>: http://dev.bar.com
<span class="hl-attribute" style="color: #7f007f;"> name</span>: Developer Setup
<span class="hl-attribute" style="color: #7f007f;">prod</span>:
<span class="hl-attribute" style="color: #7f007f;"> url</span>: http://foo.bar.com
<span class="hl-attribute" style="color: #7f007f;"> name</span>: My Cool App</pre>
</pre>
</div>
</div>
</div>
<div>
<br /></div>
<div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Placeholders and dynamic resolution</span></h4>
</div>
<div>
<div style="color: #333333; font-family: Helvetica, Arial, Freesans, Clean, sans-serif; line-height: 25.600000381469727px; margin-bottom: 15px;">
Using the <code class="literal" style="background-color: #f2f2f2; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgb(204, 204, 204); color: #6d180b; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 16px; padding: 1px 3px 0px; text-shadow: none; white-space: nowrap;">@Value("${property}")</code> annotation to inject configuration properties can sometimes be cumbersome, especially if you are working with multiple properties or your data is hierarchical in nature. Spring Boot provides an alternative method of working with properties that allows strongly typed beans to govern and validate the configuration of your application. For example:</div>
<pre class="programlisting" style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); clear: both; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 15px; line-height: 1.4; overflow: auto; padding: 6px 10px;"><em><span class="hl-annotation" style="color: grey;">@Component</span></em>
<em><span class="hl-annotation" style="color: grey;">@ConfigurationProperties(prefix="connection")</span></em>
<span class="hl-keyword" style="color: #7f0055; font-weight: bold;">public</span> <span class="hl-keyword" style="color: #7f0055; font-weight: bold;">class</span> ConnectionSettings {
<span class="hl-keyword" style="color: #7f0055; font-weight: bold;">private</span> String username;
<span class="hl-keyword" style="color: #7f0055; font-weight: bold;">private</span> InetAddress remoteAddress;
<span class="hl-comment" style="color: #3f5f5f; font-style: italic;">// ... getters and setters</span>
}</pre>
</div>
<div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Uses a Java based variant: </span></div>
<div>
<br /></div>
<pre class="programlisting" style="background-color: #f8f8f8; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(204, 204, 204); clear: both; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 15px; line-height: 1.4; overflow: auto; padding: 6px 10px;"><em style="background-color: transparent; line-height: 1.4;"><span class="hl-annotation" style="color: grey;">@Configuration
</span></em><em style="line-height: 1.4;"><span class="hl-annotation" style="color: grey;">// @Profile("production")
</span></em><em style="line-height: 1.4;"><span class="hl-annotation"><span style="color: grey;">@EnableAutoConfiguration(exclude={EmbeddedDatabaseConfiguration.class})
</span></span></em><span class="hl-keyword" style="color: #7f0055; font-weight: bold; line-height: 1.4;">public</span><span style="line-height: 1.4;"> </span><span class="hl-keyword" style="color: #7f0055; font-weight: bold; line-height: 1.4;">class</span><span style="line-height: 1.4;"> MyConfiguration {
</span><span style="line-height: 1.4;">}</span></pre>
<br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">4. Apache Deltaspike</span></h3>
<div>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px; margin-bottom: 9px;">
The Apache DeltaSpike configuration system enables providing a default configuration inside the binary and allowing to amend this configuration (e.g. database credentials, some URLs from remote REST or SOAP endpoints, etc) from outside like environment settings, JNDI or the current <a href="http://deltaspike.apache.org/projectstage.html" style="color: #0088cc; text-decoration: none;">ProjectStage</a>.</div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Drop-In Configuration</span></h4>
<span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; font-weight: normal; line-height: 18px;">The mechanism also allows for dynamic configuration in case of a JAR drop-in. By adding some JAR to the classpath, all it's contained configuration will get picked up and considered in the property value evaluation. You could also use this mechanism to switch implementations of some SPI (Service Provider Interface) in your own code.</span><br />
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">CDI-Extension Configuration</span></h4>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px; margin-bottom: 9px;">
In some cases low-level configs are needed e.g. during the bootstrapping process of the CDI container.</div>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px; margin-bottom: 9px;">
The good news: our DeltaSpike configuration mechanism does not rely on any other EE mechanism to be booted. Which means it can perfectly get used to even configure those parts itself. Since the mechanism doesn't rely on CDI it can for example be used to configure CDI-Extensions.</div>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px; margin-bottom: 9px;">
Currently this is e.g. used to configure the value of the current <a href="http://deltaspike.apache.org/projectstage.html" style="color: #0088cc; text-decoration: none;">ProjectStage</a>, configured values which can be used in the expressions for <code style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; padding: 2px 4px;">@Exclude</code>, 'Deactivatable', etc. DeltaSpike needs such a low-level approach for several features internally, but users can utilize it for their own needs as well. This is done by using the <code style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; padding: 2px 4px;">ConfigResolver</code> which resolves and caches <code style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; padding: 2px 4px;">ConfigSource</code>s per application.</div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Userland Configuration</span></h4>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px; margin-bottom: 9px;">
DeltaSpike also provides a mechanism to inject those configured values using the <code style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; padding: 2px 4px;">@ConfigProperty</code> CDI Qualifier.</div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">ConfigSources provided by default</span></h4>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px; margin-bottom: 9px;">
Per default there are implementations for the following config sources (listed in the lookup order):</div>
<ul style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px; list-style-image: initial; list-style-position: initial; margin: 0px 0px 9px 25px; padding: 0px;">
<li>System properties (deltaspike_ordinal = 400)</li>
<li>Environment properties (deltaspike_ordinal = 300)</li>
<li>JNDI values (deltaspike_ordinal = 200, the base name is "java:comp/env/deltaspike/")</li>
<li>Properties file values (apache-deltaspike.properties) (deltaspike_ordinal = 100, default filename is "META-INF/apache-deltaspike.properties")</li>
</ul>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px; margin-bottom: 9px;">
It's possible to change this order and to add custom config sources.</div>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px; margin-bottom: 9px;">
To add a custom config-source, you have to implement the interface <code style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; padding: 2px 4px;">ConfigSource</code> and register your implementation in a file <code style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; padding: 2px 4px;">/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource</code> by writing the fully qualified class name of the custom implementation/s into it.</div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Type-safe configuration</span></h4>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px; margin-bottom: 9px;">
Finally DeltaSpike provides also a way to directly inject configured values into your code via the qualifier <code style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12px; padding: 2px 4px;">@ConfigProperty</code>.</div>
<div class="codehilite" style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 18px;">
<pre style="background-color: whitesmoke; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; border: 1px solid rgba(0, 0, 0, 0.14902); font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12.025px; margin-bottom: 9px; padding: 8.5px; white-space: pre-wrap; word-break: break-all; word-wrap: break-word;"><span class="nd" style="color: #aa22ff;">@ApplicationScoped</span>
<span class="kd" style="color: green; font-weight: bold;">public</span> <span class="kd" style="color: green; font-weight: bold;">class</span> <span class="nc" style="color: blue; font-weight: bold;">SomeRandomService</span>
<span class="o" style="color: #666666;">{</span>
<span class="nd" style="color: #aa22ff;">@Inject</span>
<span class="nd" style="color: #aa22ff;">@ConfigProperty</span><span class="o" style="color: #666666;">(</span><span class="n">name</span> <span class="o" style="color: #666666;">=</span> <span class="s" style="color: #ba2121;">"endpoint.poll.interval"</span><span class="o" style="color: #666666;">)</span>
<span class="kd" style="color: green; font-weight: bold;">private</span> <span class="n">Integer</span> <span class="n">pollInterval</span><span class="o" style="color: #666666;">;</span>
<span class="nd" style="color: #aa22ff;">@Inject</span>
<span class="nd" style="color: #aa22ff;">@ConfigProperty</span><span class="o" style="color: #666666;">(</span><span class="n">name</span> <span class="o" style="color: #666666;">=</span> <span class="s" style="color: #ba2121;">"endpoint.poll.servername"</span><span class="o" style="color: #666666;">)</span>
<span class="kd" style="color: green; font-weight: bold;">private</span> <span class="n">String</span> <span class="n">pollUrl</span><span class="o" style="color: #666666;">;</span>
<span class="o" style="color: #666666;">...</span>
<span class="o" style="color: #666666;">}</span></pre>
</div>
</div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">5. Apache Commons Configuration</span></h3>
<div>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin-bottom: 10px;">
Configuration parameters may be loaded from the following sources:</div>
<ul style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin: 0px 0px 10px 25px; padding: 0px;">
<li>Properties files</li>
<li>XML documents</li>
<li>Windows INI files</li>
<li>Property list files (plist)</li>
<li>JNDI</li>
<li>JDBC Datasource</li>
<li>System properties</li>
<li>Applet parameters</li>
<li>Servlet parameters</li>
</ul>
<span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px;">Different configuration sources can be mixed using a </span><tt style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 20px; padding: 3px 4px;">ConfigurationFactory</tt><span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px;"> and a </span><tt style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 20px; padding: 3px 4px;">CompositeConfiguration</tt><span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px;">. Additional sources of configuration parameters can be created by using custom configuration objects. This customization can be achieved by extending</span><tt style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 20px; padding: 3px 4px;">AbstractConfiguration</tt><span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px;"> or </span><tt style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; line-height: 20px; padding: 3px 4px;">AbstractFileConfiguration</tt><span style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px;">.</span><br />
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin-bottom: 10px;">
The full Javadoc API documentation is available <a href="http://commons.apache.org/proper/commons-configuration/apidocs/index.html" style="color: #0088cc; text-decoration: none;">here</a>.</div>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin-bottom: 10px;">
For manipulating properties or their values the following methods can be used:</div>
<dl style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px; margin-bottom: 20px;">
<dt style="font-size: 1.2em; font-weight: bold; margin: 15px 0px 5px;"><tt style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; padding: 3px 4px;">addProperty()</tt></dt>
<dd style="margin-left: 10px;">Adds a new property to the configuration. If this property already exists, another value is added to it (so it becomes a multi-valued property).</dd>
<dt style="font-size: 1.2em; font-weight: bold; margin: 15px 0px 5px;"><tt style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; padding: 3px 4px;">clearProperty()</tt></dt>
<dd style="margin-left: 10px;">Removes the specified property from the configuration.</dd>
<dt style="font-size: 1.2em; font-weight: bold; margin: 15px 0px 5px;"><tt style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; padding: 3px 4px;">setProperty()</tt></dt>
<dd style="margin-left: 10px;">Overwrites the value of the specified property. This is the same as removing the property and then calling <tt style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, 'Courier New', monospace; padding: 3px 4px;">addProperty()</tt> with the new property value.</dd>
<dt style="font-size: 1.2em; font-weight: bold; margin: 15px 0px 5px;"><tt style="background-color: #f7f7f9; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; border: 1px solid rgb(225, 225, 232); color: #dd1144; font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 12px; padding: 3px 4px;">clear()</tt></dt>
<dd style="margin-left: 10px;">Wipes out the whole configuration</dd></dl>
</div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">6. Mechanism provided with the JDK</span></h3>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">System Properties</span></h4>
<h4>
<div style="font-weight: normal;">
<div style="margin-bottom: 10px;">
<div style="color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Of course the well known Java system properties are always an easy way to configure things. By adding additional properties on the command line starting the Java process additional properties can be defined, e.g.</span></div>
<div style="color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><br /></span></div>
<div style="color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;">java -Dfoor.bar=notYet <mainClass></span></div>
<div style="color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><br /></span></div>
<div style="color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">will start the given </span><span style="font-family: Courier New, Courier, monospace;"><mainClass></span><span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">. Hereby the value from foor.bar can be extracted by calling </span><span style="font-family: Courier New, Courier, monospace;">System.getProperty("foo.bar"); </span><span style="font-family: Arial, Helvetica, sans-serif;">This mechanism is widely used, but also has its limitations, mainly because it is a global configuration mechanism (the value is the same for the whole VM). Also adding very large amounts of system properties may lead to comlpex installation and deployment scenarios.</span></div>
</div>
</div>
</h4>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">java.util.Properties</span></h4>
<div>
<div style="margin-bottom: 10px;">
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Of course, you could use simple property files. E.g. you can add a property file </span><span style="font-family: Courier New, Courier, monospace;">foobar.properties</span><span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"> to your classpath (or a file, if you like)and then read it using the corresponding reader methods:</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;">Properties props = new Properties();</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;">props.read(getClass().loadResource("foobar.properties");</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Additionally the JDK also support storing properties using a XML format:</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;">Properties props = new Properties();</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;">props.readfromXML(getClass().loadResource("foobar.properties");</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px;">
Unfortunately there is no support for overriding of properties. So this mechanism is very limited.</div>
<h4 style="background-color: white; color: black; font-size: medium; line-height: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">java.util.Preferences</span></h4>
<div>
<div style="margin-bottom: 10px;">
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">Another API present in the JDK is </span><span style="font-family: Courier New, Courier, monospace;">java.util.preferences</span><span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;">. It models a tree of nodes, where each node can have arbitrary attributes:</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;">Prefereces systemPrefs = Preferences.systemRoot();</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;">Prefereces userPrefs = Preferences.userRoot();</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;">String configuredValue = systemPrefs.get("a.b.c.myKey", "myDefaultValue");</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;">int configuredIntValue = userPrefs.get("my.foo.intValue", 190);</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">The key used above hereby resolve to paths in the tree, so </span><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">"a.b.c.myKey", references the following node:</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;"><root></span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;"> \_ a</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;"> \_ b</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;"> \_ c</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: Courier New, Courier, monospace;">myKey</span><span style="font-family: Arial, Helvetica, sans-serif;"> is finally the key looked up in the node c.</span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;"><br /></span></div>
<div style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">Basically a node supports the following data types:</span></div>
<div style="background-color: white;">
</div>
<ul style="background-color: white; color: #333333; font-size: 12px; line-height: 20px;">
<li><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">String</span></li>
<li><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">int</span></li>
<li><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">long</span></li>
<li><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">float</span></li>
<li><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">double</span></li>
<li><span style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;">byte[]</span></li>
</ul>
<span style="background-color: white; color: #333333; font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="font-size: 12px; line-height: 20px;">So the API is simple but in practice has shown to be very limited and not appropriate as a base for modelling configuration, because</span></span><br />
<div style="background-color: white;">
</div>
<div style="background-color: white;">
</div>
<ul style="background-color: white;">
<li><span style="color: #333333; font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="font-size: 12px; line-height: 20px;">The API's absrtactions are modelled by abstract classes, which prevents the flexibility required.</span></span></li>
<li><span style="color: #333333; font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="font-size: 12px; line-height: 20px;">Registering additional PreferencesFactory instances (SPI) may interfere with texisting code.</span></span></li>
<li><span style="color: #333333; font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="font-size: 12px; line-height: 20px;">Access to the tree is widely synchronized, which is not acceptable for accessing configuration in a EE environment.</span></span></li>
<li><span style="color: #333333; font-family: Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="font-size: 12px; line-height: 20px;">The Preferences SPI also supports writing configuration back, but is in combination with remote backends basically very cumbersome to implement and use.</span></span></li>
</ul>
<div style="background-color: white;">
</div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">7. JFig</span></h3>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: small; font-weight: normal;">See </span><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;"><a href="http://jfig.sourceforge.net/">http://jfig.sourceforge.net/</a></span></span><br />
<br />
<span style="font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small;">JFig allows developers to:</span></span></span><br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small; font-weight: normal;">Store application configuration in one common repository of XML files</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small; font-weight: normal;">Access configuration data using one common, convenient interface</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small; font-weight: normal;">Easily define multiple configurations, dynamically modifying those variables that need to change in different situations.</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small; font-weight: normal;">Eliminate the error prone practice of defining the same configuration variables in multiple locations</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small; font-weight: normal;">Ease the management, deployment, and control of configuration files</span></span></li>
</ul>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;">JFig structures configuration as a hierarchy of configuration files. It supports .xml and .ini files:</span></span></span></h3>
<h3>
<div class="MsoBodyText" style="font-size: medium; font-weight: normal; margin: 0in 0in 6pt;">
<b>XML Format<o:p></o:p></b></div>
<div class="MsoBodyText" style="font-size: medium; font-weight: normal; margin: 0in 0in 6pt;">
<span style="font-family: Courier New, Courier, monospace;"><configuration></span></div>
<div class="MsoBodyTextIndent" style="font-size: medium; font-weight: normal; margin: 0in 0in 6pt 0.25in;">
<span style="font-family: Courier New, Courier, monospace;"><include name=”base.config.xml”/></span></div>
<div class="MsoNormalIndent" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt;">
<span style="font-family: Courier New, Courier, monospace;"> <section name=”locos”></span></div>
<div class="ShortReturnAddress" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt; text-indent: 0.5in;">
<span style="font-family: Courier New, Courier, monospace;"><entry key=”instance” value=”development” /></span></div>
<div class="MsoNormalIndent" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt;">
<span style="font-family: Courier New, Courier, monospace;"> </section></span></div>
<div class="MsoList2" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.5in; text-indent: -0.25in;">
<span style="font-family: Courier New, Courier, monospace;"><section name=”Paths”></span></div>
<div class="MsoList2" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.5in; text-indent: 0in;">
<span style="font-family: Courier New, Courier, monospace;"><entry key=”locosHome” value=”d:/[locos]{instance}/project/” /></span></div>
<div class="MsoList2" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.5in; text-indent: 0in;">
<span style="font-family: Courier New, Courier, monospace;"><entry key=”locosExternal” value=”d:/external/[locos]{instance}/” /></span></div>
<div class="MsoList2" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.5in; text-indent: -0.25in;">
<span style="font-family: Courier New, Courier, monospace;"></section></span></div>
<div class="MsoNormal" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt;">
<br /></div>
<div class="MsoNormalIndent" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.25in;">
<span style="font-family: Courier New, Courier, monospace;"><section name=”attachments”></span></div>
<div class="MsoNormalIndent" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.5in;">
<span style="font-family: Courier New, Courier, monospace;"><entry key=”attachmentDirectory” value=”[paths]{locosExternal}attachments/”/></span></div>
<div class="MsoNormalIndent" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt;">
<span style="font-family: Courier New, Courier, monospace;"> </section></span></div>
<div class="MsoBodyText" style="font-size: medium; font-weight: normal; margin: 0in 0in 6pt;">
<span style="font-family: Courier New, Courier, monospace;"></configuration></span></div>
<div class="MsoBodyText" style="font-size: medium; font-weight: normal; margin: 0in 0in 6pt;">
<br /></div>
<div class="MsoBodyText" style="font-size: medium; font-weight: normal; margin: 0in 0in 6pt;">
<b>INI File Format<o:p></o:p></b></div>
<div class="MsoBodyText" style="font-size: medium; font-weight: normal; margin: 0in 0in 6pt;">
Section names are in brackets, followed by key/value pairs.</div>
<div class="MsoBodyText" style="font-size: medium; font-weight: normal; margin: 0in 0in 6pt;">
Following is a sample file:</div>
<div class="MsoList" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.25in; text-indent: -0.25in;">
<span style="font-family: Courier New, Courier, monospace;">[project]</span></div>
<div class="MsoList" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.25in; text-indent: -0.25in;">
<span style="font-family: Courier New, Courier, monospace;">instance=development</span></div>
<div class="MsoList" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.25in; text-indent: -0.25in;">
<span style="font-family: Courier New, Courier, monospace;">timeout=5</span></div>
<div class="MsoNormal" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt;">
<br /></div>
<div class="MsoList" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.25in; text-indent: -0.25in;">
<span style="font-family: Courier New, Courier, monospace;">[Paths]</span></div>
<div class="MsoList" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.25in; text-indent: -0.25in;">
<span style="font-family: Courier New, Courier, monospace;">locosHome=d:/project/[locos]{instance}/</span></div>
<div class="MsoList" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.25in; text-indent: -0.25in;">
<span style="font-family: Courier New, Courier, monospace;">locosExternal=d:/[locos]{instance}/</span></div>
<div class="MsoNormal" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt;">
<br /></div>
<div class="MsoList" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.25in; text-indent: -0.25in;">
<span style="font-family: Courier New, Courier, monospace;">[attachments] </span></div>
<div class="MsoList" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.25in; text-indent: -0.25in;">
<span style="font-family: Courier New, Courier, monospace;">attachmentDirectory=[paths]{locosHome}attachments/</span></div>
<div class="MsoList" style="font-size: medium; font-weight: normal; margin: 0in 0in 0.0001pt 0.25in; text-indent: -0.25in;">
<br /></div>
<span style="font-size: small; font-weight: normal;">Hereby JFig allows to read multiple files. The “include” directive instructs the JFig parser to find the included configuration file. Files are parsed in reverse order. Thus, if a prod config file includes a base config file, the base config is parsed first. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"></span><br />
</h3>
<br />
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Variable Substitution</span></h4>
<span style="font-family: Arial, Helvetica, sans-serif;">The system provides substitution and cross referencing of variables. Substitution variables are in the format:</span><span style="font-family: Courier New, Courier, monospace;"> [section]{key}</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span><span style="font-size: 16px;"> </span><span style="font-family: Arial, Helvetica, sans-serif;">The second value, section <i>Paths</i>, key <i>locosHome</i>, uses the value of project, instance to build its value. So, <i>locosHome </i>resolves to </span><span style="font-family: Courier New, Courier, monospace;">d:/project/development</span><span style="font-family: Arial, Helvetica, sans-serif;"> . The next entry, <i>attachmentDirectory</i>, uses the previous entry to build its value. Thus, <i>attachmentDirectory </i>resolves to </span><span style="font-family: Courier New, Courier, monospace;">d:/project/development/attachment</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: Arial, Helvetica, sans-serif;">Also JFig allows to reference system properties:</span></div>
<div style="margin-bottom: 10px;">
<span style="background-color: white; font-size: 16px; text-indent: 48px;"><entry key=”docomentDir” value=”<b>$user.home$</b>/documents” /></span><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Accessing Configuration</span></h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Configuration then can be accessed as follows:</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;">JFig.getInstance().getValue(sectionName, key) </span><span style="font-family: Arial, Helvetica, sans-serif;">Or </span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: Courier New, Courier, monospace;">JFig. getInstance().getValue(sectionName, key, defaultValue)</span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: Arial, Helvetica, sans-serif;">If you use a default value and the section/key is not found, the default value will return. If you don’t use a default value and the section/key is not found, </span><span style="font-family: Courier New, Courier, monospace;">ConfigException </span><span style="font-family: Arial, Helvetica, sans-serif;">is thrown.<br /><br />To set JFig values, use </span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: Courier New, Courier, monospace;">JFig.setConfigurationValue(sectionName, key, newValue);</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">For the most part, however, config values are set during the initial parsing of one or more ini files.</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">To show a complete listing of JFig values, use </span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: Courier New, Courier, monospace;">JFig.getInstance().printConfigurationDictionary()</span><br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">8. Carbon</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;"><br />See <a href="http://carbon.sourceforge.net/modules/core/docs/config/Usage.html">http://carbon.sourceforge.net/modules/core/docs/config/Usage.html</a></span><span style="background-color: white; font-family: verdana, arial, geneva, sans-serif; font-size: 13px;">The Carbon configuration model takes two steps to improve the use of externalized data files for configuration. The first is to provide a simple configuration hierarchy based on the model of folders and documents. The second is to provide more advanced integration between the data and code using something called data binding. This provides much more advanced error checking as well as a consistent method for managing the data and most importantly strongly-typed access to the data.</span></div>
<div style="margin-bottom: 10px;">
<span style="background-color: white; font-family: verdana, arial, geneva, sans-serif; font-size: 13px;">The primary interface to configuration data is through extensions of the </span><i style="background-color: white; font-family: verdana, arial, geneva, sans-serif; font-size: 13px;">Configuration</i><span style="background-color: white; font-family: verdana, arial, geneva, sans-serif; font-size: 13px;"> interface. The configuration service, through data binding, is able to implement any interface that extends the </span><i style="background-color: white; font-family: verdana, arial, geneva, sans-serif; font-size: 13px;">Configuration</i><span style="background-color: white; font-family: verdana, arial, geneva, sans-serif; font-size: 13px;"> interface and adheres to the JavaBean™ Specification for properties.</span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">package examples; </span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-size: x-small;">public interface WebServiceConfiguration extends Configuration {</span></span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-size: x-small;"> String getServiceName();</span></span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> void setServiceName(String value); String getServiceAddress();</span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> void setServiceAddress(String serviceAddress);</span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> boolean isSecureConnection();</span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> void setSecureConnection(boolean secureConnection);</span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> Class TransportClass = org.apache.soap.transport.SOAPHTTPConnection.class;</span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> Class getTransportClass(); void setTransportClass(Class value);</span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="font-size: x-small;">}</span></span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: Arial, Helvetica, sans-serif;">A Carbon configuration file then would look as follows:</span></div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><Configuration ConfigurationInterface="examples.WebServiceConfiguration"><br /> <ServiceName>HelloWorld</ServiceName><br /> <ServiceAddress>http://ws.examples/HelloWorld</ServiceAddress><br /> <SecureConnection>true</SecureConnection></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"></Configuration></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The configuration can then be accessed as follows:</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">WebServiceConfiguration myConfig = (WebServiceConfiguration)<br /> Config.getInstance().fetchConfiguration("/WS/example"); </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">if (myConfig.isSecure()) { <br /> // ... use ssl socket factory<br /> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">} </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">else {</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"> // ... </span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">use standard socket factory </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> ... </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">} </span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;">Transport transport = myConfig.getTransportClass().newInstance(); transport.send(new URL(myConfig.getServiceAddress()), "hello", // .....</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Additionally there is also a weakly typed variant:</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><Configuration ConfigurationInterface="org.sape.carbon.core.config.PropertyConfiguration"><br /> <MyInt>4</MyInt></span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <MyFloat>6.6</MyFloat></span><span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <MyString>Hello, World!</MyString><br /> <MyClass>org.sape.carbon.core.config.format.test.ConfigurationFormatServiceTest<br /> </MyClass> </span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"> <Name> <First>John</First> <Last>Doe</Last> </Name></span></div>
<div style="margin-bottom: 10px;">
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"></Configuration></span></div>
<div style="margin-bottom: 10px;">
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Which can be accessed as follows:</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"><br /></span></div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"></span><br />
<div style="margin-bottom: 10px;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">int num = myConfig.getIntProperty("MyInt");</span><span style="font-family: Courier New, Courier, monospace; font-size: x-small;">String firstname = </span>myConfig.getProperty("Name.First");</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">9. Owner</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">See <a href="https://github.com/lviggiano/owner">https://github.com/lviggiano/owner</a></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<div style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 25.6000003814697px; margin-bottom: 16px;">
The approach used by OWNER is to define a Java interface associated to a properties file.</div>
<div style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 25.6000003814697px; margin-bottom: 16px;">
Suppose your properties file is defined as <code style="background-color: rgba(0, 0, 0, 0.0392157); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; line-height: normal; margin: 0px; padding: 0.2em 0px;">ServerConfig.properties</code>:</div>
<div class="highlight highlight-properties" style="background: rgb(255, 255, 255); box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 25.6000003814697px; margin-bottom: 16px;">
<pre style="background-color: #f7f7f7; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="na" style="box-sizing: border-box; color: teal;">port</span><span class="o" style="box-sizing: border-box; font-weight: bold;">=</span><span class="s" style="box-sizing: border-box; color: #df5000;">80</span>
<span class="na" style="box-sizing: border-box; color: teal;">hostname</span><span class="o" style="box-sizing: border-box; font-weight: bold;">=</span><span class="s" style="box-sizing: border-box; color: #df5000;">foobar.com</span>
<span class="na" style="box-sizing: border-box; color: teal;">maxThreads</span><span class="o" style="box-sizing: border-box; font-weight: bold;">=</span><span class="s" style="box-sizing: border-box; color: #df5000;">100</span>
</pre>
</div>
<div style="box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 25.6000003814697px; margin-bottom: 16px;">
To access this property you need to define a convenient Java interface in <code style="background-color: rgba(0, 0, 0, 0.0392157); border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; line-height: normal; margin: 0px; padding: 0.2em 0px;">ServerConfig.java</code>:</div>
<div class="highlight highlight-java" style="background: rgb(255, 255, 255); box-sizing: border-box; color: #333333; font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; font-size: 16px; line-height: 25.6000003814697px; margin-bottom: 16px;">
<pre style="background-color: #f7f7f7; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="kd" style="box-sizing: border-box; font-weight: bold;">public</span> <span class="kd" style="box-sizing: border-box; font-weight: bold;">interface</span> <span class="nc" style="box-sizing: border-box; color: #445588; font-weight: bold;">ServerConfig</span> <span class="kd" style="box-sizing: border-box; font-weight: bold;">extends</span> <span class="n" style="box-sizing: border-box;">Config</span> <span class="o" style="box-sizing: border-box; font-weight: bold;">{</span>
<span class="kt" style="box-sizing: border-box; color: #445588; font-weight: bold;">int</span> <span class="nf" style="box-sizing: border-box; color: #945277; font-weight: bold;">port</span><span class="o" style="box-sizing: border-box; font-weight: bold;">();</span>
<span class="n" style="box-sizing: border-box;">String</span> <span class="nf" style="box-sizing: border-box; color: #945277; font-weight: bold;">hostname</span><span class="o" style="box-sizing: border-box; font-weight: bold;">();</span>
<span class="kt" style="box-sizing: border-box; color: #445588; font-weight: bold;">int</span> <span class="nf" style="box-sizing: border-box; color: #945277; font-weight: bold;">maxThreads</span><span class="o" style="box-sizing: border-box; font-weight: bold;">();</span>
<span class="o" style="box-sizing: border-box; font-weight: bold;">}</span>
</pre>
</div>
<div style="box-sizing: border-box; color: #333333; font-size: 16px; line-height: 25.6000003814697px; margin-bottom: 16px;">
<span style="font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif;">OWNER calls this interface the <em style="box-sizing: border-box;">Properties Mapping Interface</em> or just <em style="box-sizing: border-box;">Mapping Interface</em> since its goal is to map </span><span style="font-family: Courier New, Courier, monospace;">Properties </span><span style="font-family: Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif;">into a an easy to use piece of code. </span><span style="font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif; line-height: 25.6000003814697px;">Finally, you can let OWNER read and assign your config as follows:</span></div>
<div class="highlight highlight-java" style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; box-sizing: border-box; margin-bottom: 16px;">
<pre style="background-color: #f7f7f7; border-bottom-left-radius: 3px; border-bottom-right-radius: 3px; border-top-left-radius: 3px; border-top-right-radius: 3px; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 14px; line-height: 1.45; overflow: auto; padding: 16px; word-break: normal; word-wrap: normal;"><span class="n" style="box-sizing: border-box;">ServerConfig</span> <span class="n" style="box-sizing: border-box;">cfg</span> <span class="o" style="box-sizing: border-box; font-weight: bold;">=</span> <span class="n" style="box-sizing: border-box;">ConfigFactory</span><span class="o" style="box-sizing: border-box; font-weight: bold;">.</span><span class="na" style="box-sizing: border-box; color: teal;">create</span><span class="o" style="box-sizing: border-box; font-weight: bold;">(</span><span class="n" style="box-sizing: border-box;">ServerConfig</span><span class="o" style="box-sizing: border-box; font-weight: bold;">.</span><span class="na" style="box-sizing: border-box; color: teal;">class</span><span class="o" style="box-sizing: border-box; font-weight: bold;">);</span></pre>
<span style="font-family: Arial, Helvetica, sans-serif;">This looks rater simple and straight forward. But owner has a bunch of additional interesting features and is one of the most sophisticated solutions I have found so far</span><br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">default values support</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">collection support, including custom tokenizers</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">type conversion support</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">overriding mechanisms</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">placeholders (called variable expansion) and dynamic resolution</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">mutability and configuration hot reload (both synchronous and asynchronous)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">listening to reload events</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">explicit modelling of accessibility and mutability of configuration</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Meta-Configuration</span></li>
</ul>
</div>
</div>
</div>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">
</span></div>
<div style="margin-bottom: 10px;">
<div>
<div style="margin-bottom: 10px;">
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">10. Other Configuration Mechanisms</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">I encountered several configuration frameworks and mechanism during my work life so far. Nevertheless I also want to describe one of the more powerful ones, just to show some of the features/requirements identified in bigger companies.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Typically such custom solution either use one or more of the mechanisms described above, or the companies decided to write a feasible configuration solution themselves.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Hereby it is noteable that</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">most of the solutions are based on simple <i>key, value pairs</i>, with </span><span style="font-family: Courier New, Courier, monospace;">String </span><span style="font-family: Arial, Helvetica, sans-serif;">values only.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">some companies added also support for different </span><span style="font-family: Courier New, Courier, monospace;">Collection </span><span style="font-family: Arial, Helvetica, sans-serif;">types of String, but in general this concepts has shown to add more complexity and issues than it provides advantages.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">some of them use flat keys, but most of them define a tree structure, similar to what the JDK's preferences API is doing.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">the system differentiate between the execution context, such as</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">executed during system startup (system class loader)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">executed during ear startup/shutdown (ear class loader)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">executed during application startup (application class loader)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">executed during a request, e.g. a http request, or an EJB called.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">also a stage is defined, which may look very different for different companies</span></li>
</ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">the system define different override rules, e.g.</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">system properties override everythging</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">application properties override ear config</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">ear config overrides system config</span></li>
</ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">some of them also map <i>environment,system properties and the command line arguments</i> into the global configuration tree.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">some also use additional environment settings, such as tier, network zone, security policy, server or JVM/app server instance names to define further possibilities for customizing the final configuration active.</span></li>
</ul>
<div>
<br /></div>
</div>
</div>
</div>
<div style="background-color: white; color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 12px; line-height: 20px;">
<br /></div>
</div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com65tag:blogger.com,1999:blog-6710986841844568686.post-38337958741007416082014-08-22T16:15:00.003-07:002014-10-11T05:52:59.930-07:00<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Injecting and Updating Configuration
</span></h2>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">At the last Hackergarten in Zurich, I discussed some configuration aspects with Andres Almiray (Twitter: @aalmiray). He showed my some very interesting aspects in the Griffon framework concerning injecting and updating String based configuration (<a href="https://github.com/griffon-plugins/griffon-preferences-plugin">preferences plugin</a>). Image the following bean:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">@Singleton</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>public class</b> MyConfiguredBean{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Configured</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>private</b> String myConfigValue;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically this is simple and realizable just using today's existing CDI mechanisms, where </span><span style="font-family: 'Courier New', Courier, monospace;">@ConfiguredProperty</span><span style="font-family: Arial, Helvetica, sans-serif;"> is simply injecting the corresponding configuration value with the key "</span><span style="font-family: 'Courier New', Courier, monospace;">myConfigValue</span><span style="font-family: Arial, Helvetica, sans-serif;">" (the field name). Of course, if the field name is not, what you want, you can explicitly define the configuration key to be used.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">@Singleton</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>public class</b> MyConfiguredBean{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Configured(key="a.b.configValue")</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>private</b> String myConfigValue;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Given that declaration the configuration system will just inject the correct configuration value once, when the bean is initialized. Now interesting could be how we can define an easy mechanism, to make the bean aware of configuration changes on the given property. With CDI, we could simply add a ConfigChangeEvent, which will be provided for each Configuration Change:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">@Singleton</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>public class</b> MyConfiguredBean{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @Configured(key="a.b.configValue")</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>private</b> String myConfigValue;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>public void</b> configChanged(@Observes ConfgChangeEvent evt){</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This would be easy. Furthermore we can add en injection mechanism, where the changes can directly be applied to the current bean:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>public void</b> configChanged(@Observes ConfigChangeEvent evt){</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> evt.applyChanges(<b>this</b>);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This would implicitly update all the configuration injected, including </span><span style="font-family: Courier New, Courier, monospace;">Strings</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">If we look at the example above, we basically can make things even easier (and that is what Griffon has already built-in): we simply add another top level annotation on the bean, telling the configuration system, that it should automatically reinject configuration values, when they change:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">@AutoConfigured</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">@Singleton</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b>public class</b> MyConfiguredBean{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> @ConfiguredProperty(key="a.b.configValue")</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>private</b> String myConfigValue;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So whenever I access </span><span style="font-family: Courier New, Courier, monospace;">myConfigValue</span><span style="font-family: Arial, Helvetica, sans-serif;">, I will see the current accurate result. I think this is an easy and intuitive way for managing String based configuration. Nevertheless this mechanism must not be constraint to Strings, it can be used for <i>any configured resource</i>.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
</div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com1tag:blogger.com,1999:blog-6710986841844568686.post-8842705376880340212014-05-31T15:21:00.001-07:002014-06-01T13:28:09.873-07:00Use Case Summary from Google Groups<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Use Cases</span></h2>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">In todays blog, I am summarizing the use cases as discussed in <a href="http://groups.google.com/forum/#!forum/java-config">groups.google.com/forum/#!forum/java-config</a></span><span style="font-family: Arial, Helvetica, sans-serif;">. I did only some minor rework on the original posts and hope to still reflecting the essence right.</span></div>
<div>
<div>
<div id="content">
<div class="sect1">
<div class="sectionbody">
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Configurable Priorities</span></h3>
</div>
<div class="paragraph" id="ScenarioSources">
<span style="font-family: Arial, Helvetica, sans-serif;">
The configuration system in DeltaSpike uses, what they call, <em>sources </em><a href="http://deltaspike.apache.org/configuration.html#configsource">http://deltaspike.apache.org/configuration.html#configsource</a>). Configuration hereby comes from several
sources :
</span></div>
<div class="ulist">
<ul>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
System properties
</span><br />
</li>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
Environment properties
</span><br />
</li>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
JNDI values
</span><br />
</li>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
Properties file values (default filename is
"META-INF/apache-deltaspike.properties")
</span><br />
</li>
</ul>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
These sources have a </span><i style="font-family: Arial, Helvetica, sans-serif;">default </i><span style="font-family: Arial, Helvetica, sans-serif;">priority (System first…. properties
file last) that can be changed. So we could easily say "by
default, the </span><i><span style="font-family: Arial, Helvetica, sans-serif;">WEB-INF/classes</span></i><span style="font-family: Arial, Helvetica, sans-serif;"> directory is a source that
has a priority lower that an <i>external file</i>". This way, by
default, if there is a config file within a war, it will have
lower priority, meaning Java EE components will behave as they
use to. By adding an external source this (defaults) can be overriden or extended. And of course,
this default behavior can be changed.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">→</span><span style="font-family: Arial, Helvetica, sans-serif;"> Configuration comes from different sources.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">→ Configuration must be combinable.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">→ Configuration must have
different priorities that may taken into account, when combining
configuration.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="paragraph">
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Configurable Overrides</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Overriding behavior must be configurable, e.g. refer to the way of the Jersey team does things. You can
register components and given them a priority. This approach
would allow us to provide a default chain of sources of
configuration properties and to allow the user to specify his
own chain.
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ Configuration can be evaluated by a complex combination of sub-configurations or providers (e.g. a chain of responsibility)</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">→
Different environments may require different combinations in place</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Multi Tenancy</span></h3>
</div>
<div class="paragraph" id="ScenarioMultiTenancy">
<span style="font-family: Arial, Helvetica, sans-serif;">
In multi tenancy setups a hierarchical/graph model of contexts
for configurations is required. For example there might be some
kind of layering:
</span></div>
<div class="ulist">
<ul>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
Layer 0: Default App configuration
</span><br />
</li>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
Layer 1: Tenant specific configuration
</span><br />
</li>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
Layer 2: User specific configuration
</span><br />
</li>
</ul>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
Configurations made in the tenant or user layer override the
default app configuration etc.
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ Configuration must be orgainizable in layers that can
override/extend each other.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">→ The current environment must be
capable of mapping tenant, user and other aspects, so a
corresponding configuration (or layer) can be derived.
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="sect2">
<h3 id="ScenarioOperations">
<span style="font-family: Arial, Helvetica, sans-serif;">Scenario Operations
</span></h3>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
Current support of Java EE for operations (e.g. PaaS
offerings) is weak. Also corresponding providers may not be
fully compatible, which makes it more difficult to move
applications between providers or different offerings/products
within the same provider. Hereby a provider requires an
extension to the EE runtime model, where all relevant
deployment configuration can be controlled by an external source,
managed by the provider and consumed by the EE platform. </span><span style="font-family: Arial, Helvetica, sans-serif;">Basically if one deploys a java application a standard way to
define it’s configuration, resources and environment to
integrate with the provisioning tooling in place should be defined. </span><span style="font-family: Arial, Helvetica, sans-serif;">The configuration should be pluggable (e.g. from a database, an external file,…) and the configuration should also be changeable at runtime.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Also there should be a standardized way to evaluate a
configuration for an already deployed application.</span><br />
<br /></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ EE deployments must be configurable. Configuration must be
controllable from external sources, which are not controlled
by the EE container.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ External resource can override all aspects, or only
override/extend specific parts, but still consider
configuration data deployed with the application.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ a contract is required, how this external configuration can
be included/provided.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ a contract is required, how according configuration is
modelled, so the external source can "implement" the contract.
</span><br />
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">→ Configuration may be fully or partially mutable.</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">→ Changes on configuration must be observable.</span></div>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ a service is required that allows to read out the
configuration of a deployed application.
</span></div>
<div class="paragraph">
<br />
<br />
<h3 id="ScenarioOperations">
<span style="font-family: Arial, Helvetica, sans-serif;">Injectable Configuration and Fragments</span></h3>
</div>
<div class="paragraph">
</div>
<div class="paragraph" id="ScenarioDeveloper">
<span style="font-family: Arial, Helvetica, sans-serif;">
As a developper I want to be able to configure my
application/module something like this :
</span></div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay"><span style="color: #008888;"><b>public</b></span><code class="java language-java"> MyPojo {
<span style="color: #008888;"><b>private</b></span> <span style="color: #00aa88;"><b>String</b></span> currency;
<span style="color: #008888;"><b>private</b></span> <span style="color: #00aa88;"><b>Long</b></span> currencyRate;
<span style="color: #777777;">// complex algorithm based on the currency</span>
}</code></pre>
<pre class="CodeRay"><code class="java language-java">
</code></pre>
</div>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
How do I configure that depending if my app is dealing with
dollars or euros ? The DeltaSpike way of doing is something
like :
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay"><span style="color: #008888;"><b>public</b></span><code class="java language-java"> MyPojo {
<span style="color: #000077;">@Inject</span> <span style="color: #000077;">@Config</span>(<span style="color: #771100;">"</span><span style="color: #dd2200;">myCurrency</span><span style="color: #771100;">"</span>)
<span style="color: #008888;"><b>private</b></span> <span style="color: #00aa88;"><b>String</b></span> currency;
<span style="color: #000077;">@Inject</span> <span style="color: #000077;">@Config</span>(<span style="color: #771100;">"</span><span style="color: #dd2200;">myCurrencyRate</span><span style="color: #771100;">"</span>)
<span style="color: #008888;"><b>private</b></span> <span style="color: #00aa88;"><b>Long</b></span> currencyRate;
<span style="color: #777777;">// complex algorithm based on the currency</span>
}</code></pre>
<pre class="CodeRay"><code class="java language-java">
</code></pre>
</div>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
The Seam Config way of doing is quite clever. They use a
namespace that is relative to the packing. So, without
changing the initial code (so, forget about the @Inject above)
they have an XML file that is able to override each attribute
of any file.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
As a Java EE user (developer or devops) I would like also to
be able to package different versions of deployment descriptor
fragments within my Java EE application archive, and be able
to select which one is used via a <code>-D</code> command line
argument.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
E.g. have the following file structure within the application
archive (a <code>.war</code> in this case):
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay"><code class="listing language-listing">WEB-INF
conf
dev
web-fragment.xml
qa
web-fragment.xml
live
web-fragment.xml</code></pre>
<pre class="CodeRay"><code class="listing language-listing">
</code></pre>
</div>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
And then either directly be able to say that <code>conf/dev/web-fragment.xml</code>
should be used, or do this indirectly via an include directive
and a placeholder in the main deployment descriptor for this
type of fragment (in this case <code>web.xml</code>):
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay"><span style="color: #007700;"><b><web-app></b></span><code class="xml language-xml">
...
<span style="color: #007700;"><b><fragment></b></span>WEB-INF/conf/${mycompany.staging}/web-fragment.xml<span style="color: #007700;"><b></fragment></b></span>
<span style="color: #007700;"><b></web-app></b></span></code></pre>
<pre class="CodeRay"><code class="xml language-xml"><span style="color: #007700;"><b>
</b></span></code></pre>
</div>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ Application Configuration must be supported.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ Configuration must be injectable using CDI
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ Configuration should support fragements, which can
dynamically loaded by properties on the current runtime
environment, or other mechanisms.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<h3 id="ScenarioTesting">
<span style="font-family: Arial, Helvetica, sans-serif;">Scenario Testing</span></h3>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">When testing a Java EE solution, it must be possible to easily control the configuration provided, so isolated component tests can be written effectively. Also it should be possible to control/isolate the configuration level for each test case.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">→ isolation of configuration services</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">→ API for controlling the configuration provided, required for according implementations in the testing frameworks.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
</div>
</div>
<div class="sect2">
<h3 id="ScenarioModules">
<span style="font-family: Arial, Helvetica, sans-serif;">Scenario Modules
</span></h3>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
Complex applications are often built out of many more fine
granular pieces, often called modules or plugins. This could
be technical abstractions, business models, products or UI
components. All of them require some configuration, which may
be different for different runtime deployments (e.g. product
customizations).
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ it must be possible to add configuration that exceeds the EE
deployment aspects (Application Configuration).
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ this configuration must be deployable in different ways,
along the code, or from external sources.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
</div>
<div class="sect2">
<div class="paragraph">
</div>
</div>
<div class="sect2">
<h3 id="ScenarioStaging">
<span style="font-family: Arial, Helvetica, sans-serif;">Scenario Staging
</span></h3>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
Different companies go through different staging levels during
the development of software components. Currently only rarely
the EE frameworks support staging aspects, nevertheless no
broader, well modelled staging concept is defined. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Different
companies also have different staging or sub-staging levels in
place, which also must be reflected. Especially with
sub-stages inheritance of stage related configuration is
common sense and should be supported.
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ Main stages available and to be supported by Java EE must be
defined.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ Enable sub-stages, additional aspects to be added, so also
custom stages can be supported by configuration.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ Allow stage properties inheritance, where needed.
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
</div>
<div class="sect2">
<h3 id="ScenarioCotsIntegration">
<span style="font-family: Arial, Helvetica, sans-serif;">Custom of the Shelf (COTS) Integration
</span></h3>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
When buying software from an external software company it is
often very cumbersome to integrate, adapt and customize third
party software to the internal operational requirements.
Especially, when software is delivered as ear modules
portability is often very difficult and time consuming.
Configuration should enable COTS providers to define a
customization contract, which also can be part of the COTS
software interface and integration specifications. This would
allow operations to better control and configure third party
solutions as possible, whereas in the evaluation phase the
integration and configuration options can explicitly be
defined.
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ It must be possible to document configuration aspects
supported.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ It must be possible to configure arbitrary aspects, with
basically arbitrary complexity, exceeding what is defined by
Java EE.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ Configuration must be overridable from external sources (the
operations which must operate the COTS solution).
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="paragraph" id="ScenarioAutoDeployment">
<span style="font-family: Arial, Helvetica, sans-serif;">
When operating huge server farms targeting Java EE solutions a
typical process is as follows:
</span></div>
<div class="olist arabic">
<ol class="arabic">
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
An order for a Java EE deployment is created.
</span><br />
</li>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
An according logical domain is created and prepared image
with a standard setup is installed.
</span><br />
</li>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
The logical domain and the containing Java EE application
server are started in standalone mode.
</span><br />
</li>
<li>
<span style="font-family: Arial, Helvetica, sans-serif;">
The application(s) are copied to the server and
automatically deployed.
</span><br />
</li>
</ol>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
Hereby it would ease life of administrators, if deployment of
EE solutions can be controlled/automated by the application
server. This requires that the application server can be
startup in some "maintenance mode", which allows to trigger
its configuration service, so according deployments can be
controlled by some (external) deployment controller.
</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
</div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ Configuration must be injectable/deployable also into a
running application server.
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ It must be possible to listen to configuration changes, so
the deployment could be controlled similarly based on
configuration changes (events).
</span></div>
<div class="paragraph">
<span style="font-family: Arial, Helvetica, sans-serif;">
→ configuration must be mutable and changes observable. </span></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<br /></div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Some Conclusions</span></h3>
<h2>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: small; font-weight: normal;">So taking all into account, I would suggest the following:</span></h2>
</div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration is a very complex thing (OK, this is not new).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration is dependent on the environment.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration can be static and/or dynamic.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration can come in different flavors and types.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Different companies have different sources and external systems in place, where and how they manage configurations. It must be possible to interoperate with all/most of them.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">If EE Configuration focuses only on Java EE aspects, it will fail to cover some of the most important use cases and will make Java EE to fall back much behind e.g. what Springsource or other Cloud platforms are offering already as of today.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration should leverage existing functionalities, e.g. by being injectable into CDI, instead of reinventing the wheel.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The good news is that, if interpreting configuration as a more broader and generic concept all/most of these aspects can be covered quite well with only a few abstractions. Though having said that, I am not sure, what will be covered at the end. Nevertheless th</span><span style="font-family: Arial, Helvetica, sans-serif;">e benefits for application programmers in Java EE would be tremendous, even if only a few aspects will be targeted. </span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">One of the risks I currently see, is that configuration aspects are targeted in a too narrow sense, focusing on leveraging EE as a platform only, because</span></div>
</div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">focusing on EE only may not require to model configuration in a generic way, which may reduce the flexibility achieved at the end. Especially it might constrain the interoperability of configuration per se or, even worse, it might lead to two different ways of configuration in the future: one for application logic, one for EE logic.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">adding configuration to all the existing JSRs is a huge and tremendous effort. To try to drive (remodel?) all required changes out of one JSR may quite probably make it fail. Nevertheless, focusing on the most important EE aspects, like EJBs, CDI, servlets, JSF, JMS, JPA, would still create huge benefits, but leave enough time for other aspects described above.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">As always, you can add your comments or, even better, add your use cases, you want to be solved, so we can ensure we have covered the most important ones here...</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com1tag:blogger.com,1999:blog-6710986841844568686.post-68137635497614698582014-05-26T04:38:00.001-07:002014-05-26T04:42:23.935-07:00A Proposal for Java EE Configuration (Follow up)<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">
A Proposal for Java EE Configuration (Follow up)</span></h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Given all the feedback and discussions from last week I would come up with the following more concrete feature list, what should be covered IMO. Finally I outline a rough server lifecycle including configuration. As always feedback is welcome!</span><br />
<br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">High Level Features</span></h3>
<ul>
<li><span style="background-color: white; color: #222222; font-family: arial, sans-serif;">Define mechanisms to enable applications being deployed by adding configuration externally (from an application viewpoint). This means it must be theoretically possible to configure an application completely externally. This would include loading and providing existing deployment descriptors and other configuration files to be provided based on external configuration.</span></li>
</ul>
<ul>
<li><span style="background-color: white; color: #222222; font-family: arial, sans-serif;">Define mechanisms to provide deployment descriptors, e.g. by some API or more generic, accessible under certain keys. Alternatively a common configration access point for EE configuration is defined that can be used, by other JSRs.</span></li>
</ul>
<ul>
<li><span style="background-color: white; color: #222222; font-family: arial, sans-serif;">From a DevOps perspective, also additional aspects, today configured outside of an ear/war archive should be considered, such as security setup, data sources, message queues, worker thread pools etc. This is also one of the more interesting areas, where we must see in what kind of runtime environment we are running. If CDI 2.0 would define some shared system level container, this will be the place to be, if not application servers must load EnvironmentManager and ConfigurationManager and provide them as JNDI entries.</span></li>
</ul>
<ul>
<li><span style="background-color: white; color: #222222; font-family: arial, sans-serif;">Application configuration is also very important for portability. A key/value store has shown in a variety of frameworks its strengths, so with another 10+ interfaces this feature should also be included. </span></li>
</ul>
<ul>
<li><span style="background-color: white; color: #222222; font-family: arial, sans-serif;">Wiri</span><span style="background-color: white; color: #222222; font-family: arial, sans-serif;">n</span><span style="background-color: white; color: #222222; font-family: arial, sans-serif;">g and injection of the effective configuration should be done based on CDI. </span></li>
</ul>
<br />
<br />
<div>
<h3 style="background-color: white;">
<span style="font-family: Arial, Helvetica, sans-serif;">Additional Details</span></h3>
</div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Environments are hierarchic, meaning environment settings from lower levels, e.g. startup are also visible in inheriting contexts, but may be overriden. Environments also define the basic hierarchy levels for configuration.</span></li>
</ul>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">At a current runtime point exact one environment is active.</span></li>
</ul>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">An environment provides a Stage, which is predefined. Additional custom stages can be realized by adding additional properties to the environment. An SPI allow to add additional values to an environment.</span></li>
</ul>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration (parts) can be active/non active based on the current environment.</span></li>
</ul>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">All configured String values support EL syntax to be used for wildcards and cross-references and dynamic replacements.</span></li>
</ul>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Default values can be deployed along the code by adding configuration to a configuration.xml loaded deployed with the code on the classpath.</span></li>
</ul>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Application Configuration basically is modelled along the environment hierarchy and thus runtime dependent, whereas deployment configuration is identified by the requested target state.</span></li>
</ul>
<br />
<div>
<div class="gmail_extra" style="background-color: white;">
<div class="gmail_quote">
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Portable and Externalizable Application Configuration</span></h3>
<div>
<ul>
<li><span style="color: #222222; font-family: arial, sans-serif;">A common </span><span style="color: #222222;"><span style="font-family: Courier New, Courier, monospace;">application.xml</span></span><span style="color: #222222; font-family: arial, sans-serif;"> file (name and location to be discussed) will be defined, which summarizes all/most configuration aspects as of today. </span></li>
</ul>
<ul>
<li><span style="color: #222222; font-family: arial, sans-serif;">Similarly a programmatic Java API is defined that allows to configure an application, modelling the same features as the <span style="font-family: 'Courier New', Courier, monospace;">application.xml</span>. An instance of such an object can be injected as a configuring resource into the CDI container (e.g. </span><span style="color: #222222;"><span style="font-family: Courier New, Courier, monospace;">ApplicationConfiguration</span></span><span style="color: #222222; font-family: arial, sans-serif;">). From a user's persepctive this can be an implementation based on the </span><span style="color: #222222;"><span style="font-family: Courier New, Courier, monospace;">application.xml</span></span><span style="color: #222222; font-family: arial, sans-serif;"> (default) or provided by any other mechanism (including external ones).</span></li>
</ul>
<ul>
<li><span style="color: #222222; font-family: arial, sans-serif;">Configuration may be accessed using a restful service API, that is not active by default.</span></li>
</ul>
</div>
</div>
</div>
<div class="gmail_extra" style="background-color: white; color: #222222;">
<div class="gmail_quote">
<div class="gmail_default">
<h3 style="color: black; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></h3>
<h3 style="color: black; font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;">Out of Scope</span></h3>
<div>
<ul>
<li><span style="font-family: arial, sans-serif;">Versioning of </span><span style="font-family: Courier New, Courier, monospace;">Configuration </span><span style="font-family: arial, sans-serif;">may be addressed later.</span></li>
</ul>
<ul style="font-family: arial, sans-serif;">
<li>The key/value API will be minimal (mostly API only and injection into managed beans). As an advantage most of existing configuration mechanisms could be used to implement the backend needed. Standardizing this mechanism fully for SE will be out of scope for this JSR and might be solved in another separate JSR.</li>
</ul>
</div>
</div>
<div class="gmail_default" style="font-family: arial, sans-serif;">
<div style="font-size: large;">
<br /></div>
<h3 style="font-size: large;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br class="Apple-interchange-newline" />A possible Server Lifecycle</span></h3>
<div>
<div class="gmail_extra">
<div class="gmail_quote">
<div style="color: black; font-family: 'Times New Roman'; font-size: medium;">
<h4>
<span style="color: #222222; font-family: arial, sans-serif;">1)<b> Server startup</b>:</span></h4>
</div>
<div style="color: black; font-family: 'Times New Roman'; font-size: medium;">
</div>
<br />
<ul>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">the shared system (CDI 2.0 ?) container is starting up. This maybe a CDI based container (preferred) or an application server specific one.</span></li>
</ul>
<ul>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">the configuration JSR root components are loaded as part of the system container and made accessible via JNDI, mainly</span></li>
</ul>
<br />
<ul>
<br />
<ul>
<li style="margin-left: 15px;"><span style="font-family: Courier New, Courier, monospace;">EnvironmentManager</span></li>
</ul>
<ul>
<li style="margin-left: 15px;"><span style="font-family: Courier New, Courier, monospace;">ConfigurationManager</span></li>
</ul>
<br />
</ul>
<ul>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">If the system container is built on CDI the following aspects are injectable:</span></li>
<ul>
<li style="margin-left: 15px;"><span style="font-family: Courier New, Courier, monospace;">EnvironmentManager</span></li>
<li style="margin-left: 15px;"><span style="font-family: Courier New, Courier, monospace;">ConfigurationManager</span></li>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">(Current) </span><span style="font-family: Courier New, Courier, monospace;">Environment</span></li>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">(Current) </span><span style="font-family: Courier New, Courier, monospace;">Stage</span></li>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">(Current) </span><span style="font-family: Courier New, Courier, monospace;">Configuration</span></li>
</ul>
</ul>
<ul>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">When the current server configuration has been loaded, a </span><b style="font-family: Arial, Helvetica, sans-serif;">config loaded event</b><span style="font-family: Arial, Helvetica, sans-serif;"> should be triggered, containing also a reference to the current s</span><i style="font-family: Arial, Helvetica, sans-serif;">ystem </i><span style="font-family: Courier New, Courier, monospace;">Configuration</span><span style="font-family: Arial, Helvetica, sans-serif;">. This event can be used to configure early server resources.</span></li>
</ul>
<h4 style="font-size: large;">
2) <b>Ear/War startup:</b></h4>
<ul>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">For each ear (and/or for each war):</span></li>
</ul>
<ul>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">load "application" CDI context, consider the configuration provided from the system container to configure application CDI.</span></li>
</ul>
<ul>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">Trigger a </span><b style="font-family: Arial, Helvetica, sans-serif;">config preload event</b><span style="font-family: Arial, Helvetica, sans-serif;">, that the </span><i style="font-family: Arial, Helvetica, sans-serif;">application </i><span style="font-family: Courier New, Courier, monospace;">Configuration</span><span style="font-family: Arial, Helvetica, sans-serif;"> will be loaded now.</span></li>
</ul>
<ul>
<li style="margin-left: 15px;"><span style="font-family: Arial, Helvetica, sans-serif;">Trigger a </span><b style="font-family: Arial, Helvetica, sans-serif;">config loaded event</b><span style="font-family: Arial, Helvetica, sans-serif;">, that the </span><i style="font-family: Arial, Helvetica, sans-serif;">application </i><span style="font-family: Courier New, Courier, monospace;">Configuration </span><span style="font-family: Arial, Helvetica, sans-serif;">has been loaded and now is available (containing the current <span style="font-family: 'Courier New', Courier, monospace;">Configuration</span>).</span></li>
</ul>
<span style="font-family: arial, sans-serif;">All features, including application configuration are fully based/extending CDI. JNDI entries for </span><span style="font-family: Courier New, Courier, monospace;">EnvironmentManager, ConfigurationManager </span><span style="font-family: arial, sans-serif;">are still the same (access restrictions are to be discussed). If we have some kind of shared a CDI context on system level of the container, we could fully build the configuration system based on CDI.</span></div>
<div style="font-size: large;">
<span style="font-family: arial, sans-serif;"><br /></span></div>
</div>
</div>
</div>
</div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com11tag:blogger.com,1999:blog-6710986841844568686.post-49275742986351289162014-05-15T06:31:00.000-07:002014-05-26T04:38:44.286-07:00A Proposal for Java EE Configuration<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">
Requirements for Java EE Configuration</span></h2>
<span style="font-family: Arial, Helvetica, sans-serif;">In this post I want to outline, what I see a reasonable scope for a Java EE Configuration JSR. I would first try to summarize different use cases, people want to have to be covered. In a next part I try to deduce corresponding requirements. Finally I will try to discuss, what is needed to cover these aspects.</span><br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Use Cases</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">First I will summarize the use cases that were mentioned so far in the discussion, especially also <a href="https://groups.google.com/forum/#!topic/java-config/FrgH9_O1qkU">here</a>.</span><br />
<br />
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;">An enterprise wants to centrally control their deployments (could be cloud, but is not restricted to). Hereby according configuration should be managed externally within a database or some other kind of data container. The configuration should be accessible with an administrative console and it should be possible to change configuration and remotedly update running instances affected by a configuration change. Especially administrative resources, such as data sources, thread pools, users, roles etc. should be configurable, so these aspects can be managed in a central location.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">For different stages or runtime environments different CDI components should be loaded that reflect the different runtime environments. This includes configuring CDI, Enterprise Java Beans and similar aspects (basically everything that can be configured with some kind of deployment constructor deployed with an ear or war archive).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Depending on the stage and some additional aspects different configuration must be used (including, but not limited to deployment profiles). Advanced use cases include network zones, host, tier, server instance and more. Hereby the possible properties are not constraint and may heavily differ between applications and especially enterprises (runtime environments). Many applications use a file based configuration approach, which is often cumbersome and error prone.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It should be possible to adapt/reconfigure COTS applications to better accomodate them into the concrete environments. It should be possible to deploy them on different stages, without having to redeploy anything (also because traceability of the deployment may be a legal requirement).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It should be possible to provide configuration that goes beyond what is defined by the current EE standards. E.g. there are companies that redeploy the exact some jars in different setups, but reconfigure them (e.g. in multitenant, multiproduct scenarios). Thinking in extremes that could mean having a single application deployed multiple times very differently.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration should be accessible both using a Java API, as well as being injected using CDI mechanisms.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It should be easily possible to use this configuration mechanism also in testing. Developers should be capable of easily configure their test setup that should be loaded.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Similar to views in relational database configuration should be scoped, so only a subset is visible. This can be required for example because of security concerns.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Finally for multi-tenant/SaaS setups configuration must be dynamic, so a SaaS provider can lookup configuration programmatically.</span></li>
</ol>
<br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Requirements</span></h3>
<div>
</div>
<br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This list is quite probably not complete. Nevertheless it is possible to deduce some requirements:</span></div>
<div>
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It must be possible to store and manage configuration at an arbitrary place independent of the target deployments.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It must be possible to store and manage configuration along the target deployments.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It must be possible to provide configuration with deployment artifacts (jars, wars, ears)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It must be possible to mix configuration from different locations.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It must be possible to priorize configuration.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It must be possible to combine configuration in different ways (override, extend, ignore duplicates, ...).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It must be possible to change configuration and trigger the changes to interesting observers.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration must be loadable within early boot of a system, where no EE context is available.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration must be adaptable depending on the current runtime context.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration must be accessible/injectable using CDI mechanisms.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration must be accessible using a Java based API.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration services must allow to configure</span><span style="font-family: Arial, Helvetica, sans-serif;"> administrative resources, such as datasources, users, roles.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The runtime environment must be modeled in a flexible way, because different companies have different deployment/runtime and consequenty configuration needs.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration must support staging. It would be possible to define a minimal staging type applied to an environment, But such a concept would require to allow concrete sub-stages to be modellable to accommodate also complex runtime environments.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration should be able to support a wide range of EE. </span><span style="font-family: Arial, Helvetica, sans-serif;"> If some areas would be excluded, we would stop half-way and destroying much of the benefits a powerful configuration mechanism can provide, since we in such case have to do workarounds as before.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration may be marked as read-only. An simple accessor should allow to determine if configuration is mutable.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration must be thread-safe.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Whereas configuration itself must not be serializable, it must be possible to extract a current state of configuration and serialize this state (e.g. as immutable configuration). This enables sending configuration easily over network connections.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration must also support aspects that are currently not part of any EE standard, especially it must be possible to also configure application aspects. Without that you simply have to do workarounds to mitigate this lacking feature, distrying the benefits of other configurations.</span></li>
</ol>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The list is for sure not yet complete, but I tend to say the most important aspects are covered. If you are something missing, let me know, so I can extend the list above.</span></div>
</div>
<br />
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Conclusions</span></h3>
</div>
<br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Give the huge areas of use cases above, one may think, it it will not be possible to define a useful scope for a JSR. I would fully agree, if one would try to solve everything from scratch modeling every aspect explicitly. But why should we? Configuration is per se quite an abstract concept, as we have seen also in previous blogs here. So lets keep configuration abstract and simple (KISS principle):</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Configuration = Map<String,String> + Metadata</i></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Metadata = Name + Map<String,String></i></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Finally we need some mechanism to access configuration. Given the requirements above it is not useful, to define configuration access as an interface injectable by CDI only, since it will prevent us of using configuration at early stages, where CDI is not loaded yet. Similarly it would not be possible to use configuration for configuring administrative resources. But if we would fail to cover these requirements, it is quite useless to file a JSR for this topic.</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So basically configuration must IMO be provided by some simple accessor as a global service. Now some people might argue that this is not EE styled. So I would ask, what EE is all about, so I look up Wikipedia:</span></div>
<blockquote class="tr_bq">
<span style="font-family: Trebuchet MS, sans-serif;">"Java EE provides an API and runtime environment for developing and running enterprise software, includingnetwork and web services, and other large-scale, multi-tiered, scalable, reliable, and secure network applications. Java EE extends the Java Platform, Standard Edition (Java SE), providing an API for object-relational mapping, distributed and multi-tier architectures, and web services."</span></blockquote>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So there is nothing said that is can not be done in that way. Additionally, we have some additional benefits:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">There is a clear separation of concerns. The configuration service has a clear, well defined API, how it can be accessed and what kind of features it must provide. The configuration service itself does basically not neet to know anything about its EE context, which is the way how modularized systems are built as of today.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">We have defined a simple interface, that allows us to hook in different kind of implementations and solutions to provide configuration. For example any vendor can provide additional configuration management tools and products that allow to manage your application server configuration centrally thus also creating additional benefits (and profits).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Basically it can be left over to the implementations how the configuration provided is stored and retrieved. The JSR should focus on the mechanisms and interfaces, not on how different companies should manage their configurations.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The interface and the access points must be defined by the JSR, but the effective data feeds can still be adapted to the needs of the concrete usage scenarios.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Said that, this also enables us to support configuration in SE cases, especially for testing. Especially when CDI would also be configurable, it can be used (e.g. with CDI 2.0) in combination with configuration services also in test environments very effectively, which would simplify testing of EE a lot.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Over the years the former complex and over-engineered EJB design was transformed into a lean POJO (POJI) based easy to use component model, where additional services and cross-cutting concerns can simply be annotated. It would look very strange if we would add a configuration mechanism that again only works within a EE context.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Additionally there are other possible things that might be useful:</span></div>
</div>
<br />
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Finally configuration of application aspects is also required. Defining a generic and easily accessible configuration service allows to cover these aspects similarly, without having to file another JSR. Defining some additional annotations to be used with CDI for injecting configuration into managed beans should be rather trivial. Advanced use cases hereby may be ommitted and left over for future releases.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">provide configuration in different versions.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">node and cluster based configuration.</span></li>
</ul>
</div>
<br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So there is IMO a strong coincidence for going that way, because</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">the mechanism is simple</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">the mechanism builds on top of existing interfaces (</span><span style="font-family: Courier New, Courier, monospace;">Map</span><span style="font-family: Arial, Helvetica, sans-serif;">), hereby also supporting features such as Lambdas and streams out of the box</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">the mechanism is not intersecting with CDI, because it is constraint.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">String keys and values, can easily be combined and filtered, so aspects included above can be easily supported:</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">filtering/views</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">templating/defaults</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">intersections</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">unions</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">...</span></li>
</ul>
</ul>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">One of the following key aspects would be, how we then integrate this new functîonality with all the existing JSRs? Basically there are two different possible ways to go forward:</span></div>
<div>
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The JSR itself defines, how each JSR must support adaptable configuration.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The JSR defines the basic mechanism. The JSRs to be included into EE8 should define on their own, how they want to make use the new mechanisms. Hereby the EE8 umbrella JSR group, lead by Bill Shannon and Linda DeMichels are coordinating the initiative.</span></li>
</ol>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">I personally think going for (1) is not the way, it should be. I think each JSR itself has the best know how, what might be feasible points of integration with the new configuration services. Additionally this would also help to reduce the scope of the Configuration JSR drastically. As a precondition to that, the API to be used should be defined and stable very early in the overall process. My idea would be to have it defined the latest until end of this year (assuming we can file the JSR within next few weeks). So we have two years time to integrate it into the existing standards, which looks for me a reasonable time frame. At the same time I would suggest the configuration JSR provides some kind of guidelines and corresponding templates, so the other JSRs can easily adopt the new mechanism. As an example a template could look something like that:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<br />
<table border="1" cellpadding="0" cellspacing="0" dir="ltr" style="border-collapse: collapse; border: 1px solid #ccc; font-family: arial,sans,sans-serif; font-size: 13px; table-layout: fixed;"><colgroup><col width="217"></col><col width="174"></col><col width="183"></col><col width="433"></col></colgroup><tbody>
<tr style="height: 21px;"><td data-sheets-value="[null,2,"External Configuration for JSR 220"]" style="border-bottom: 1px solid #000000; font-size: 180%; font-weight: bold; padding: 2px 3px 2px 3px; vertical-align: bottom;">Configuration<br />
for JSR 220</td><td style="border-bottom: 1px solid #000000; padding: 2px 3px 2px 3px; vertical-align: bottom;"></td><td style="border-bottom: 1px solid #000000; padding: 2px 3px 2px 3px; vertical-align: bottom;"></td><td style="border-bottom: 1px solid #000000; padding: 2px 3px 2px 3px; vertical-align: bottom;"></td></tr>
<tr style="height: 21px;"><td data-sheets-value="[null,2,"Configuration Key"]" style="background-color: #d9d9d9; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; font-weight: bold; padding: 2px 3px 2px 3px; vertical-align: bottom;">Configuration Key</td><td data-sheets-value="[null,2,"Configuration Type"]" style="background-color: #d9d9d9; border-bottom: 1px solid #000000; border-right: 1px solid #000000; font-weight: bold; padding: 2px 3px 2px 3px; vertical-align: bottom;">Configuration Type</td><td data-sheets-value="[null,2,"Availability"]" style="background-color: #d9d9d9; border-bottom: 1px solid #000000; border-right: 1px solid #000000; font-weight: bold; padding: 2px 3px 2px 3px; vertical-align: bottom;">Availability</td><td data-sheets-value="[null,2,"Expected Content"]" style="background-color: #d9d9d9; border-bottom: 1px solid #000000; border-right: 1px solid #000000; font-weight: bold; padding: 2px 3px 2px 3px; vertical-align: bottom;">Expected Content</td></tr>
<tr style="height: 21px;"><td data-sheets-value="[null,2,"javax.jpa.persistenceUnits"]" style="border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding: 2px 3px 2px 3px; vertical-align: bottom;">javax.jpa.persistenceUnits</td><td data-sheets-value="[null,2,"java.lang.String"]" style="border-bottom: 1px solid #000000; border-right: 1px solid #000000; padding: 2px 3px 2px 3px; vertical-align: bottom;">java.lang.String</td><td data-sheets-value="[null,2,"application/ear startup"]" style="border-bottom: 1px solid #000000; border-right: 1px solid #000000; padding: 2px 3px 2px 3px; vertical-align: bottom;">application/ear startup</td><td data-sheets-value="[null,2,"Comma separated lists of names of the registered persistence units."]" style="border-bottom: 1px solid #000000; padding: 2px 3px 2px 3px; vertical-align: bottom;">Comma separated lists of names of the registered persistence units.</td></tr>
<tr style="height: 21px;"><td data-sheets-value="[null,2,"javax.jpa.persistenceUnit.[name]"]" style="border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding: 2px 3px 2px 3px; vertical-align: bottom;">javax.jpa.persistenceUnit.[name]</td><td data-sheets-value="[null,2,"java.io.InputStream"]" style="background-color: white; border-right-color: rgb(0, 0, 0); border-right-style: solid; border-right-width: 1px; font-size: 100%; padding: 2px 3px; vertical-align: bottom;">java.io.InputStream</td><td data-sheets-value="[null,2,"application/ear startup"]" style="border-bottom: 1px solid #000000; border-right: 1px solid #000000; padding: 2px 3px 2px 3px; vertical-align: bottom;">application/ear startup</td><td data-sheets-value="[null,2,"Deployment Descriptor (persistence.xml) as described in section XXX"]" style="border-bottom: 1px solid #000000; border-right: 1px solid #000000; padding: 2px 3px 2px 3px; vertical-align: bottom;">Deployment Descriptor (persistence.xml) as described in section XXX</td></tr>
</tbody></table>
<div>
</div>
<br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Of course, the example above is not probably not complete. But it shows the main intend quite well. </span><span style="font-family: Arial, Helvetica, sans-serif;">Nevertheless it would still be feasible that the configuration JSR makes proposals, how the other JSRs can be accomodated to the new mechanism, if other JSRs wish us to do so.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">If then finally a JSR is nevertheless failing to use the new APIs, the configuration JSR and the EE overall planning would not be affected. This greatly reduces the risk for EE8 to be delayed, but still there is a reasonable chance that we can achieve a new flexible EE platform.</span></div>
<div>
<br /></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Proposal and Scope</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Given all the aspects described above a configuration JSR will cover the following:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><b>Next:</b></span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Open the JSR</span></li>
</ul>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><b>Until end of 2014:</b></span></div>
<br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Define the Java API as far as possible</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Define a simple map based configuration abstraction, as basically outlines in my previous posts. </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Define a simple, but flexible and extendible Configuration Service (accessor) API. It consists of an accessor that is also loadable outside of CDI.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Define a SPI to configure/back the implementation used by the accessor API.</span></li>
</ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Define a configuration description template. Send it out to each JSR included in EE8, so each JSR can individually decide how the want to be configurable. The results then can be included either into updated JSRs, or/and in summarized form into the configuration JSR.</span></li>
</ul>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Basically this implies that the JSR will publish its early draft review until end of 2014.</i></span><br />
<div>
</div>
<br />
<div>
<ul></ul>
<div>
<b style="font-family: Arial, Helvetica, sans-serif;">In 2015:</b></div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Discuss and coordinate configuration support with other JSRs.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Define configuration keys/support for administrative resources.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Provide fully functional reference implementation, so it can be included into <i>Glassfish</i> as one of the first modules.</span></li>
</ul>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>This will be a reasonable scope for a Public Review during 2015.</i></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<br />
<div>
<b style="font-family: Arial, Helvetica, sans-serif;">In 2016:</b></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Finish the TCK and RI work and go final.</span></li>
</ul>
</div>
<br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Comparing with the Proposal done by Mike Keith at last Java One</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Mike Keith did several presentations during the last years at different conferences, e.g. at <a href="http://parleys.com/play/5250899ee4b0a43ac1212427/about">JavaOne 2013</a>. </span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-OE6pe1YeH7Q/U3S-EDF2yMI/AAAAAAAAElg/sr-20QmqQNA/s1600/MikeConfig.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-OE6pe1YeH7Q/U3S-EDF2yMI/AAAAAAAAElg/sr-20QmqQNA/s1600/MikeConfig.png" height="265" width="640" /></a></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Mike hereby did quite a good job, basically the use cases match very well, what is defined above here. So also this </span><span style="font-family: Arial, Helvetica, sans-serif;">proposal does not target things completely differently, but given the experience of Credit Suisse, CloudBees and other companies that run huge application server farms and cloud or cloud like infrastructures, there is one crucial aspect, where I really disagree:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><b>Do not define another archive format to provide configuration!</b></span></li>
</ul>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">There are a couple of reasons, why I think, we should not follow the idea of configuration archives as proposaed by Mike Keith:</span></div>
<div>
<ol>
<li><span style="font-family: Arial, Helvetica, sans-serif;">We already know from experience with ears and wars that handling of archives is not always easy and often is cumbersome (especially during development). Whereas also in Credit Suisse, application configuration is delivered along the code as jar artifacts, it is only covering parts of the deployment. </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Additionally the JSR would have to define the format of the archive, define the stages and other sub schemas/folders so the archive covers all kind of aspects required. This would add complexity to the configuration JSR, without benefit for users.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">In Credit Suisse Datasources, thread pools, users, security roles, certificates and other resources are not managed as file resources primarly. Within the deployment process according files are generated, by this makes the deployment inflexible, since even simple changes require a complete redeployment. Similary the deployment packages have to rebuilt for each stage. </span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Often configuration changes are assummed to be more easily deployable, but experience has shown that this must not be the case. Additionally there might be cases, where operations has to adapt a configuration, e.g. because a database or other resources has been moved. With archives the application has to be redeployed, which is exactly, what we want to prevent.</span></li>
</ol>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><b>Instead, I would let it open, how the Configuration Service effectively is locating its configuration. As shown above we can define different configurations (and locations) more effectively as shown above in the template, but without implying constraints how this configuration must be deployed.</b></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This point has been proven in discussions during the last year with leading engineers and Java Champions. Also other colluegues have written blogs on this e.g. see <a href="http://blog.loof.fr/2013/10/configuration-management-jsr.html">http://blog.loof.fr/2013/10/configuration-management-jsr.html</a></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So my proposal would be slightly adapted:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-HPtu2Vrzubo/U3S-sDF6StI/AAAAAAAAElo/W6IVo1orGK0/s1600/AnatoleConfig.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-HPtu2Vrzubo/U3S-sDF6StI/AAAAAAAAElo/W6IVo1orGK0/s1600/AnatoleConfig.png" height="255" width="400" /></a></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Higher Level Services</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">As already mentioned also at </span><span style="background-color: white; color: #666666; line-height: 16.799999237060547px; text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><a href="https://java.net/jira/browse/JAVAEE_SPEC-19">https://java.net/jira/browse/JAVAEE_SPEC-19</a></span></span><span style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 12px; line-height: 16.799999237060547px; text-align: justify;"> </span><span style="font-family: Arial, Helvetica, sans-serif;">and also as commented by Arjan Tijms, we must be capable of providing higher level services on top of that very basic concepts. Most prominent use cases are the deployment descriptors, located at several different locations throughout the system, but there are also other settings that may be considered. I outlined in the <a href="http://javaeeconfig.blogspot.com/2014/04/integrating-se-configuration-with-java.html">previous blog</a>, some of the possibilities to add additional functionalities using generic functional extensions. Tijms has outlined, that an additional <b>higher level API for providing configuration information to the different components in a EE container </b>would be useful, which may go beyond adding specialized configuration adapters. I would not disagree on that topic. </span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Basically the template idea above could then similarly extended, so instead of modelling the template entries on the low level, as described above, we would model a high level API (e.g. as an interface?), that is finally provided by the configuration JSRs. This would shield existing components from the details of the configuration service.</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Since different components in a EE container are configured rather differently, it might require to define multiple interfaces to be provided. I would like to postpone this at this point, since this topic is worth it's own blog entry ;-)</span></div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Feedback Required</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">I would like to encourage all readers to give feedback on this blog. Please do not only raise your concerns, but also give positive feedbacks, what you think. It would help to see, if this would be a feasible way to go ahead. </span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com21tag:blogger.com,1999:blog-6710986841844568686.post-46479131534062591682014-04-22T15:53:00.001-07:002014-04-22T16:06:33.043-07:00Integrating SE Configuration with Java EE<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Integrating SE Configuration with Java EE</span></h2>
<span style="font-family: Arial, Helvetica, sans-serif;">A lot of people asked about integration of configuration mechanisms with Java EE, e.g. within Java EE 8. So I write down my current thinkings on this topic here, looking forward for your opinions and thinkings.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Nature of a Deployment Descriptor</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Let's start analyzing quickly what the essence of a typical EE configuration file is, e.g. a</span> <span style="font-family: Courier New, Courier, monospace;">web.xml </span><span style="font-family: Arial, Helvetica, sans-serif;">deployment descriptor, a JPA </span><span style="font-family: Courier New, Courier, monospace;">persistence.xml </span><span style="font-family: Arial, Helvetica, sans-serif;">or a CDI </span><span style="font-family: Courier New, Courier, monospace;">beans.xml</span><span style="font-family: Arial, Helvetica, sans-serif;"> , a </span><span style="font-family: Courier New, Courier, monospace;">log4j.properties</span> <span style="font-family: Arial, Helvetica, sans-serif;">or a container specific descriptor for a datasource. What all this rather different configurations have in common? Fortunately there are quite a few common aspects:</span><br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">all configurations mentioned are <i>files</i>.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">all configurations must be deployed to some <i>well defined locations</i>.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">all its contents is basically of literal nature, in MIME types </span><span style="font-family: Courier New, Courier, monospace;">text/xml</span><span style="font-family: Arial, Helvetica, sans-serif;"> or</span><u><span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: Courier New, Courier, monospace;">text/plain</span></u>.</li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">all adhere to some<i> standards or defined formats</i></span></li>
</ul>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Advantages of Literal Configuration Files</span></h4>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">As a consequence we have some interesting options:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">literal configuration can be placed somewhere else</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">literal configuration can be "enhanced" with some kind of resolution mechanism (e.g. using expression language)</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">In other words, we can place our configuration at more or less any arbitrary location, e.g.</span></div>
</div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">we can support additional locations on the classpath</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">we can support additional file locations, e.g. as part of a domain deployment</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">we can read the configuration files from a simple web server</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">we can call some restful services to get them</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">we can manage them within a database</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">we can deploy Java classes that act as factories for providing the descriptors</span></li>
</ul>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Integrating with Java EE</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The current Java EE stack is quite simple to benefit from a configuration mechanism, when some rather simple preconditions are met:</span></div>
</div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">First of all backward compatibility must be ensured. So it must be possible to read configuration from the same places as before.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">With the new configuration mechanism in place it must be defined, how additional (external) configuration is related to probably already existing configuration</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">With <i>convention-over-configuration</i> in mind external configuration should <i>override </i>configuration at the default locations, because without external configuration everything works as expected. With external configuration provided the defaults are expected to be overridden without any further flags to be set.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">As another variant external configuration may also <i>extend </i>default configuration.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Nevertheless due to security concerns some </span><i style="font-family: Arial, Helvetica, sans-serif;">constraints </i><span style="font-family: Arial, Helvetica, sans-serif;">may be possible, these must be configured similarly.</span></li>
</ul>
</ul>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically existing JSRs also can use a configuration service in different ways:</span><br />
<h4>
<b style="font-family: Arial, Helvetica, sans-serif;">Integration on file or decriptor level</b></h4>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The most simplest way for</span><b style="font-family: Arial, Helvetica, sans-serif;"> integration is on file or decriptor level.</b><span style="font-family: Arial, Helvetica, sans-serif;"> Hereby each JSR can define and register the default locations of the deployment descriptors within the configuration service, e.g. using<i> "meta-configuration"</i>:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> <? xml version="1.0" encoding="UTF-8" ?><br /> <configuration><br /> <config name="jpa.persistence-units" type="input-files"><br /> <location>classpath*:META-INF/persistence.xml</location><br /> <override-policy>override</override-policy><br /> </config><br /> </configuration></span><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Each JSR then can use the configuration service to read the descriptors, e.g. JPA could read its </span><span style="font-family: Courier New, Courier, monospace;">persistence.xml </span><span style="font-family: Arial, Helvetica, sans-serif;">files as follows:</span><br />
<ul>
</ul>
<span style="font-family: Courier New, Courier, monospace;"> Configuration config = ...;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Collection<InputStream> persistenceUnits =</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> config.get("jpa.persistence-units", Collection.<b>class</b>);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> for(InputStream is:persistenceUnits){</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> // read persistence unit</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">The biggest advantage of this approach is that the existing JSRs require only a few minimal code changes to benefit from the new configuration service. Another advantage is that the configuration service does not any kind of knowledge on the internals of the configuration, it simply manages files.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">Nevertheless dynamic configuration resolution may be more complicated, since the configuration service does not have any know how about the internal configuration structure. Nevertheless dynamic resolution is still possible (see later in this post).</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;"><i>Note:</i> the example above uses </span><span style="font-family: Courier New, Courier, monospace;">InputStream </span><span style="font-family: Arial, Helvetica, sans-serif;">as abstraction of a file resource. Alternate types are to be discussed here, such as </span><span style="font-family: Courier New, Courier, monospace;">String </span><span style="font-family: Arial, Helvetica, sans-serif;">or </span><span style="font-family: Courier New, Courier, monospace;">URI</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span><br />
<h4>
<b style="font-family: Arial, Helvetica, sans-serif;">Full Integration</b></h4>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Another approach would be to use the configuration API to map a JSR's configuration directly. E.g. a </span><span style="font-family: Courier New, Courier, monospace;">persistence.xml </span><span style="font-family: Arial, Helvetica, sans-serif;">can be mapped as follows:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="background-color: white; font-family: Courier New, Courier, monospace;">persistence-unit.<b>myapp</b>.provider=\</span><br />
<span style="background-color: white; font-family: Courier New, Courier, monospace;"><span style="line-height: 18px;"> org.hibernate.ejb.HibernatePersistence</span></span><br />
<span style="background-color: white; font-family: Courier New, Courier, monospace;">persistence-unit.<b>myapp</b>.<span style="line-height: 18px;">jta-data-source=java:/DefaultDS</span></span></div>
<span style="background-color: white; font-family: Courier New, Courier, monospace;">persistence-unit.<b>myapp</b>.properties.myprop=myPropValue</span><br />
<span style="background-color: white; font-family: Courier New, Courier, monospace;">persistence-unit.<b>myapp</b>.properties.myprop2=myPropValue2</span><br />
<span style="background-color: white; font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="background-color: white; font-family: Arial, Helvetica, sans-serif;">In this case all types of configuration mechanism can be used to provide such a configuration. Basically it would also be possible to map an existing descriptor/configuration format by providing some according conversion classes.</span><br />
<br />
<div>
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px;">
<h3 style="font-size: medium; font-weight: normal; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">Dynamic Value Resolution</span></h3>
<div>
<div style="font-size: medium; font-weight: normal; margin: 0px; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">In many cases dynamic resolution of values simplifies things a lot (used too widely things get more complicated similarly). Also in many cases it would be sufficient to provide a basic configuration template and allow the configuration service to manage the dynamic replacements. This can be achieved, e.g. by allowing EL to be used within a configuration, e.g.</span></div>
<div style="font-size: medium; font-weight: normal; margin: 0px; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<pre class="programlisting" style="color: #333333; font-family: 'liberation mono', 'bitstream vera mono', 'dejavu mono', monospace; line-height: 18px; overflow: auto; padding: 10px 20px;"><span style="background-color: white; white-space: normal;"><persistence></span><span style="background-color: white; white-space: normal;"> <persistence-unit name="myapp"></span><span style="background-color: white; white-space: normal;"> <provider></span><span style="background-color: white;"><span style="white-space: normal;">
</span></span><span style="background-color: white; white-space: normal;">org.hibernate.ejb.HibernatePersistence
</provider></span><span style="background-color: white; white-space: normal;"> <jta-data-source></span><b style="white-space: normal;">$[config.myApp.myappDS]</b><span style="background-color: white; white-space: normal;"> </jta-data-source>
<properties>
...
</properties></span><span style="background-color: white; white-space: normal;"> </persistence-unit>
</persistence></span></pre>
<div style="font-size: medium; font-weight: normal; margin: 0px; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">or</span></div>
<div style="font-size: medium; font-weight: normal; margin: 0px; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="font-weight: normal; margin: 0px; white-space: normal;">
<span style="background-color: white; font-family: 'Courier New', Courier, monospace; font-size: x-small;"> </span><span style="background-color: white; font-family: 'Courier New', Courier, monospace;">persistence-unit.</span><b style="font-family: 'Courier New', Courier, monospace;">myapp</b><span style="background-color: white; font-family: 'Courier New', Courier, monospace;">.</span><span style="font-family: 'Courier New', Courier, monospace; line-height: 18px;">jta-data-source=</span><b style="color: #333333; font-family: 'liberation mono', 'bitstream vera mono', 'dejavu mono', monospace; line-height: 18px;">$[config.myApp.myappDS]</b></div>
<h3 style="font-size: medium; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></h3>
<h3 style="font-size: medium; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">Summary</span></h3>
<div style="font-size: medium; font-weight: normal; margin: 0px; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">Summarizing there are a couple of possible integration points. Basically all kind of EE descriptor files can be deployed at arbitrary locations, locally or remotedly, encrypted or plain or whatever is needed. With EL included dynamic resolution can be easily achieved. Finally existing JSRs can integrate with configuration services either on descriptor/file level or define a full configuration and key mapping.</span></div>
<div style="font-size: medium; font-weight: normal; margin: 0px; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="font-size: medium; font-weight: normal; margin: 0px; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">Separation of concerns into a basic configuration service and how the services are integrated with Java EE, enable also a flexible collaboration and open discussion with all the other specifications. It is also important that things are discussed early, so the other specifications have time to adopt the new features. As another side effect the same configuration mechanism can similalry be used for administrative resources or alternate environments, e.g. Tomcat, Jetty etc.</span></div>
<div style="font-size: medium; font-weight: normal; margin: 0px; white-space: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
</div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com0tag:blogger.com,1999:blog-6710986841844568686.post-58958545746162096242014-04-15T15:00:00.001-07:002014-04-15T15:30:54.605-07:00Configuration Formats and Locations<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Configuration Formats and Locations</span></h2>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Configuration Formats</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Configuration data can be stored in various formats. With the JDK a few possible formats are included by default:</span><br />
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><i>.properties</i> files, readable with </span><span style="font-family: Courier New, Courier, monospace;">java.util.Properties</span><span style="font-family: Arial, Helvetica, sans-serif;"> enable storing simple key, value pairs in an ISO-8859-1 encoded text file, also supporting Unicode escapes.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The same <span style="font-family: 'Courier New', Courier, monospace;">java.util.Properties </span>class also provides a corresponding </span><span style="font-family: Courier New, Courier, monospace;">.xml</span><span style="font-family: Arial, Helvetica, sans-serif;"> formatted variant, which benefit from all the xml encoding options.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Parameters passed with </span><span style="font-family: Courier New, Courier, monospace;">-Dkey=value</span><span style="font-family: Arial, Helvetica, sans-serif;"> on the Java command line are accessible from </span><span style="font-family: Courier New, Courier, monospace;">System.getProperties()</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Finally environment properties inherited by the underlying runtime platform are accessible from </span><span style="font-family: Courier New, Courier, monospace;">System.getenv()</span><span style="font-family: Arial, Helvetica, sans-serif;">.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">All this mechanisms are provided by the Java SE platform out of the box and therefore are widely used. But there are for sure more possible formats that might be used as source of configuration, e.g. other xml formats, JSON or databases. Therefore it makes sense to model the configuration format explicitly, so custom (or legacy) formats can be supported easily:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<br />
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #990000;">public interface</span></b> ConfigurationFormat{</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> String getFormatName();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b><span style="color: #990000;">boolean </span></b>isAccepted(URI resource);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Map<String,String> readConfiguration(URI resource);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Implementations of this class can be simply registered using different component loading mechanism, such as </span><span style="font-family: Courier New, Courier, monospace;">java.util.ServiceLoader</span><span style="font-family: Arial, Helvetica, sans-serif;"> or</span><span style="font-family: Arial, Helvetica, sans-serif;">, in case of Java EE, alternately as CDI managed bean. Access to the formats can be obtained by a corresponding singleton, which provides </span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">access to common formats, such as <i>property</i>, or <i>xml-property</i> files.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">access to other (registered) formats by name</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">access to all currently registered format names</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">access to a matching format given an URI of a resource.</span></li>
</ul>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span style="color: #990000;"><b>public final class</b></span> ConfigFormats{</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #990000;"><b>private </b></span>ConfigFormats(){}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #990000;"><b>public static</b></span> ConfigurationFormat getFormat(</span><span style="font-family: 'Courier New', Courier, monospace;"> String formatName);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="color: #990000; font-family: 'Courier New', Courier, monospace;"><b>public static</b></span><span style="font-family: Courier New, Courier, monospace;"> Collection<String> getFormatNames();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b> </b></span><span style="color: #990000; font-family: 'Courier New', Courier, monospace;"><b>public static</b></span><span style="font-family: Courier New, Courier, monospace;"> ConfigurationFormat getFormat(URI resource);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="color: #990000; font-family: 'Courier New', Courier, monospace;"><b>public static</b></span><span style="font-family: Courier New, Courier, monospace;"> ConfigurationFormat getPropertiesFormat();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="color: #990000; font-family: 'Courier New', Courier, monospace;"><b>public static</b></span><span style="font-family: Courier New, Courier, monospace;"> ConfigurationFormat getXmlPropertiesFormat();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
</div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
</div>
<div style="font-family: Arial, Helvetica, sans-serif;">
Also the singleton accessor for accessing predefined maps can be easily enriched by corresponding methods (though with increasing complexity and similar method signatures building a Builder maybe more appropriate):</div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;"><b><span style="color: #990000;">public final class</span></b> PropertyMaps{</span></div>
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;"> <b><span style="color: #990000;">private </span></b>PropertyMaps(){ }</span></div>
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;"> // factory methods</span></div>
<div style="background-color: white; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;"><span style="color: #666666;"> </span><span style="color: #990000;"><b>...</b></span></span></div>
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: 'Courier New', Courier, monospace;"> PropertyMap <b>fromPaths</b>(</span></div>
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;"> Map<String,String> metaInfo, <br /> ConfigurationFormat format, String... paths);</span></div>
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: 'Courier New', Courier, monospace;"> PropertyMap <b>fromPaths</b>(</span><span style="font-family: 'Courier New', Courier, monospace;">ConfigurationFormat format,</span><span style="font-family: 'Courier New', Courier, monospace;"> </span></div>
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;"> String... paths);</span></div>
<div style="background-color: white; color: #666666; font-family: 'Trebuchet MS', Trebuchet, Verdana, sans-serif; font-size: 13px; line-height: 18.479999542236328px;">
<span style="font-family: 'Courier New', Courier, monospace;">}</span></div>
</div>
<br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Configuration Locations</span></h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Similar to the fact that configuration data can be formatted differently, configuration can be also be read/accessed from different locations:</span><br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">as <i>class path</i> resources</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">as <i>files </i>on the locale file system</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">as resources accessible from a <i>web</i> server (or configuration server)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">as <i>remote </i>data accessible from a configuration bean (EJB, managed bean, ...)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">...</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">In the above examples/API we simply pass a literal path to locate/define a configuration. Hereby the idea is that the path is formatted in a way, so multiple location mechanisms (called readers) can be transparently added/registered to the configuration system. A configuration resource then can be defined as <</span><span style="font-family: Courier New, Courier, monospace;">reader>:<location> </span><span style="font-family: Arial, Helvetica, sans-serif;">(the ones, who know Spring will possibly see some similarities with Spring's Resource API). Examples of valid configuration resources can be:</span></div>
<div>
<ul>
<li><span style="font-family: Courier New, Courier, monospace;">classpath:cfg/test-*.xml</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">classpath*:cfg/${STAGE}/*.xml</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">file:${APP_DIR}/cfg/envconfig/*.xml</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">url:http://myconfigserver.intra.net/config/${STAGE}/get?appID=MyApp</span></li>
<li><span style="font-family: Courier New, Courier, monospace;">ds:[ConfigDS]SELECT a.key, a.value FROM Config a WHERE a.appID="MyApp"</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Hereby </span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><i>classpath </i>uses </span><span style="font-family: Courier New, Courier, monospace;">ClassLoader.getResource(String)</span><span style="font-family: Arial, Helvetica, sans-serif;">, also supporting Ant-like path expressions</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><i>classpath*</i> uses </span><span style="font-family: Courier New, Courier, monospace;">ClassLoader.getResources(String)</span><span style="font-family: Arial, Helvetica, sans-serif;">, also supporting Ant-like path expressions</span></li>
<li><i style="font-family: Arial, Helvetica, sans-serif;">file locates files on the local file system</i><span style="font-family: Arial, Helvetica, sans-serif;">, also supporting Ant-like path expressions</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><i>url</i> uses </span><span style="font-family: Courier New, Courier, monospace;">new URL(String)</span><span style="font-family: Arial, Helvetica, sans-serif;">, in the example above calling a Restful service</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><i>ds </i>accesses configuration data using an OQL query, reading from the </span><span style="font-family: 'Courier New', Courier, monospace;">ConfigDS </span><span style="font-family: Arial, Helvetica, sans-serif;">datasource.</span></li>
</ul>
</div>
</div>
<br />
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">The exact syntax for path expressions, of course, can be discussed and improved. Dynamic parts basically can be implemented using expression language (EL) extensions.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">A </span><span style="font-family: Courier New, Courier, monospace;">ConfigurationReader </span><span style="font-family: Arial, Helvetica, sans-serif;">hereby can be modeled by a simple interface as illustrated below:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #990000;">public interface</span></b> ConfigurationReader{</span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> String getReaderName();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Map<String,String> readConfiguration(String readerPath);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
</div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Similarly to formats, readers can be managed and accessed/tested from a </span><span style="font-family: Courier New, Courier, monospace;">ConfigurationReader </span><span style="font-family: Arial, Helvetica, sans-serif;">singleton:</span></div>
</div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span style="color: #990000;"><b>public final class</b></span> ConfigReaders{</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #990000;"><b>private </b></span></span><span style="font-family: 'Courier New', Courier, monospace;">ConfigReaders</span><span style="font-family: Courier New, Courier, monospace;">(){}</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #990000;"><b>public static</b></span> ConfigurationReader getReader(</span><span style="font-family: 'Courier New', Courier, monospace;"> String readerName);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="color: #990000; font-family: 'Courier New', Courier, monospace;"><b>public static</b></span><span style="font-family: Courier New, Courier, monospace;"> Collection<String> getReaderNames();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So given this interfaces and accessors our configuration model now is capable of supporting more or less every type of configuration, as long as its mappable to </span><span style="font-family: Courier New, Courier, monospace;">Map<String,String></span><span style="font-family: Arial, Helvetica, sans-serif;">. It does not imply any constraints, how configuration must be stored and managed in an enterprise, nor does it constrain the format of the input source. </span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">But even with that, there are additional things that must be considered:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration may also change. Mechanisms must be provided so configuration changes can be propagated to interested parties, both locally optionally also remotely. Such changes might also be propagated across VM boundaries e,g, by passing a serialized </span><span style="font-family: Courier New, Courier, monospace;">ChangeSet</span><span style="font-family: Arial, Helvetica, sans-serif;"> or </span><span style="font-family: Courier New, Courier, monospace;">Configuration </span><span style="font-family: Arial, Helvetica, sans-serif;">over the network.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">All examples as of now were programmatically defining the configuration to be used. Typically in an enterprise context this is determined by some configuration meta-model (aka meta-configuration).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Even worse within an application server running multiple enterprise / web applications several classloaders are active. As a consequence configuration that is provided on the classpath must be isolated along the corresponding classloader and its child class loaders.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Also we have not yet discussed how our configuration service can interoperate / being integrated in more detail within an EE environment. Integration hereby must be enabled on a global or domain level, e.g. for configuring administrative resources, but also interoperate with CDI, enabling powerful injection of configuration.</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">These are the topics for the upcoming blogs, so stay tuned!</span></div>
</div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com0tag:blogger.com,1999:blog-6710986841844568686.post-60858088518994302962014-04-01T15:42:00.004-07:002014-04-15T15:30:28.667-07:00Composite Configuration<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Composite Configuration</span></h2>
<div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Modeling Common Aspects</span></h3>
</div>
<span style="font-family: Arial, Helvetica, sans-serif;">Looking at Configuration my working analysis was to model it mainly as a </span><span style="font-family: Courier New, Courier, monospace;">Map<String,String> </span><span style="font-family: Arial, Helvetica, sans-serif;">with additional meta data added. As we have seen this concept comes with several advantages:</span><br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">The basic API ( </span><span style="font-family: Courier New, Courier, monospace;">java.util.Map</span><span style="font-family: Arial, Helvetica, sans-serif;">) is already defined by the JDK.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Since keys as well as values are simple </span><span style="font-family: Courier New, Courier, monospace;">Strings</span><span style="font-family: Arial, Helvetica, sans-serif;">, we inherit all the advantages of the final and immutable <span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: Courier New, Courier, monospace;">String</span> class, like type and thread safety.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">since we constraint our API to this simple types, we ensure no or minimal overlaps with CDI in the EE context.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">our model is fully compatible with Java SE, providing therefore maximal compatibility also with the SE platform.</span></li>
</ul>
<div>
<ul>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Applied to the configuration format we would define two distinct artifacts:</span></div>
</div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">a </span><span style="font-family: Courier New, Courier, monospace;">PropertyMap</span><span style="font-family: Arial, Helvetica, sans-serif;">, which models the minimal requirements for a configuration map.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">a </span><span style="font-family: Courier New, Courier, monospace;">Configuration</span><span style="font-family: Arial, Helvetica, sans-serif;">, which extends <span style="font-family: 'Courier New', Courier, monospace;">PropertyMap</span>and provides additional functionalities, such as extension points, type support etc.</span></li>
</ul>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #990000;">public interface</span></b> PropertyMap <b><span style="color: #990000;">extends </span></b>Map<String,String>{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Set<String> getSources();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Map<String,String> getMetaInfo(String key);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Map<String,String> getMetaInfo();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b><span style="color: #990000;">void </span></b>reload();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b><span style="color: #990000;">boolean </span></b>isMutable();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #990000;">public interface</span></b> Configuration <b><span style="color: #990000;">extends </span></b>PropertyMap{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> String getConfigId();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Boolean getBoolean(String key);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Boolean getBooleanOrDefault(String key, <br /> Boolean defaultValue);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Byte getByte(String key);</span></div>
</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <T> T getAdapted(String key, PropertyAdapter<T> adapter);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <T> T getAdaptedOrDefault(String key, <br /> PropertyAdapter<T> adapter, T defaultValue);</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <T> T get(String key, Class<T> type);</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> <T> T getOrDefault(String key, Class<T> type, </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> T defaultValue);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Set<String> getAreas();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Set<String> getTransitiveAreas();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Set<String> getAreas(Predicate<String> predicate);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Set<String> getTransitiveAreas(Predicate<String> predicate);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> boolean containsArea(String key);</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Configuration with(ConfigurationAdjuster adjuster);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <T> T query(ConfigurationQuery<T> query);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">A configuration instance then can be built using a </span><span style="font-family: Courier New, Courier, monospace;">PropertyMap</span><span style="font-family: Arial, Helvetica, sans-serif;">, e.g.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">PropertyMap myPropertyMap = ...;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Configuration config = <b><span style="color: #990000;">new </span></b>BuildableConfiguration<br /> .Builder("myTestConfig")<br /> .withUnits(myPropertyMap);</span></div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
</div>
</div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<div style="font-family: 'Times New Roman';">
<span style="font-family: Arial, Helvetica, sans-serif;">So we can provide partial configurations by just implementing the </span><span style="font-family: Courier New, Courier, monospace;">PropertyMap </span><span style="font-family: Arial, Helvetica, sans-serif;">interface. For convenience an </span><span style="font-family: Courier New, Courier, monospace;">AbstractPropertyMap </span><span style="font-family: Arial, Helvetica, sans-serif;">class can be defined that additionally supports implementing this interface. </span></div>
<div style="font-family: 'Times New Roman';">
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div style="font-family: 'Times New Roman';">
<span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #990000;">public class</span> </b>MyPropertyMap <b><span style="color: #990000;">extends </span></b>AbstractPropertyMap{</span></div>
<div style="font-family: 'Times New Roman';">
<span style="font-family: Courier New, Courier, monospace;"> <b><span style="color: #990000;">protected </span></b>Map<String,String> <b>initContentDelegate</b>(){</span></div>
<div style="font-family: 'Times New Roman';">
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #666666;">// in reality, provide something useful here...</span></span></div>
<div style="font-family: 'Times New Roman';">
<span style="font-family: Courier New, Courier, monospace;"> <b><span style="color: #990000;">return </span></b>Collections.emptyMap();</span></div>
<div style="font-family: 'Times New Roman';">
<span style="font-family: Courier New, Courier, monospace;"> }</span></div>
<div style="font-family: 'Times New Roman';">
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
</div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Using Composites to Build Complex Configurations</span></h3>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Given the simple basic </span><span style="font-family: Courier New, Courier, monospace;">PropertyMap </span><span style="font-family: Arial, Helvetica, sans-serif;">interface we can start thinking on how building more complex configurations by <i>combining </i>existing combinations. Basically the ingredients required are:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">two (or more) existing configurations</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">a combination algorithm or policy</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Now thinking on mathematical sets, we may provide similar functionality when combining configurations:</span></div>
</div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">union</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">intersection</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">subtraction</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Additionally we have to think ow we should resolve conflicts (different values with the same key), most important policies are:</span></div>
</div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><i>ignore </i>duplicates (keeping the original values from former entries)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><i>override </i>existing previous values by later values</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">throw an <i>exception</i>, when conflicting entries are encountered</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This can be modeled by a corresponding policy enum:</span></div>
</div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #990000;">public enum</span></b> AggregationPolicy{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <i>IGNORE,</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i> OVERRIDE,</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><i> EXCEPTION</i></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Finally we can provide a factory class that provides as </span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">commonly used property maps by reading from resolvable paths, using common configuration formats, e.g. <i>.property</i>-files (the resolution capabilities hereby can be extended by implementing and registering a corresponding SPI)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">most commonly used compositions of partial configurations (maps)</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This can be modeled with a simple singleton as follows:</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #990000;">public final class</span></b> PropertyMaps{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b><span style="color: #990000;">private </span></b>PropertyMaps(){ }</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #666666;">// factory methods</span></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b><span style="color: #990000;">public static</span></b> PropertyMap <b>fromArgs</b>(</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Map<String,String> metaInfo, String... args);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>fromPaths</b>(</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Map<String,String> metaInfo, String... paths);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>from</b>(</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Map<String,String> metaInfo, </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Map<String,String> map);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>fromArgs</b>(String... args);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>fromPaths</b>(String... paths);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>from</b>(Map<String,String> map);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>fromEnvironmentProperties</b>();</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>fromSystemProperties</b>();</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> // combinations</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>unionSet</b>(</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> PropertyMap... propertyMaps);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>unionSet</b>(</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> AggregationPolicy policy, <br /> PropertyMap... propertyMaps);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>intersectedSet</b>(<br /> PropertyMap... propertyMaps);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>subtractedSet</b>(</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> PropertyMap target, PropertyMap... subtrahendSets);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><b style="font-family: 'Courier New', Courier, monospace;"><span style="color: #990000;">public static</span></b><span style="font-family: Courier New, Courier, monospace;"> PropertyMap <b>filterSets</b>(</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Predicate<String> filter, PropertyMap propertyMap);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
<div style="font-family: Arial, Helvetica, sans-serif;">
With the given mechanism we are able to define complex configurations, realizing some complex override and configuration rules quite easily:</div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">String[] cliArgs = ...;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Map<String,String> defaultMap = ...;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Configuration config = <b><span style="color: #990000;">new </span></b>BuildableConfiguration.Builder(<br /> "myTestConfig").<b><span style="color: #990000;">withUnits</span></b>(</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"><b>PropertyMaps.from</b>(</span><span style="font-family: 'Courier New', Courier, monospace;">defaultMap</span><span style="font-family: 'Courier New', Courier, monospace;">),</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>PropertyMaps.fromPaths</b>("classpath:test.properties"),</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <b>PropertyMaps.fromPaths</b>("classpath:cfg/test.xml"),</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"><b>PropertyMaps.fromSystemProperties</b>(),</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="font-family: 'Courier New', Courier, monospace;"><b>PropertyMaps.fromPaths</b>(<br /> "url:http://1.2.3.4/remoteCfg.xml"),</span></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;"> </span><span style="font-family: Courier New, Courier, monospace;"><b>PropertyMaps.fromArgs</b>(</span><span style="font-family: 'Courier New', Courier, monospace;">cliArgs</span><span style="font-family: Courier New, Courier, monospace;">),</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> )</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> .<b><span style="color: #990000;">build</span></b>();</span></div>
</div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically the above creates a full fledged </span><span style="font-family: Courier New, Courier, monospace;">Configuration </span><span style="font-family: Arial, Helvetica, sans-serif;">instance that:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">is built from properties contained in the given default map.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">that may be overridden by entries in <i>test.properties</i>, read from the classpath</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">that may be overridden by entries in <i>cfg/test.xml</i>, using the JDKs xml property format (also </span><span style="font-family: Arial, Helvetica, sans-serif;">read from the classpath)</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">that may be overridden by entries from the resource loaded from <span style="font-family: 'Courier New', Courier, monospace;">http://1.2.3.4/remoteCfg.xml</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">that may be overridden by entries from the CLI arguments</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Of course, this example uses always the same keys for all different partial configuration sources, which might not be a realistic setup. But adding a mapping of provided keys to some other keys is basically a trivial task.</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Summary</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Summarizing separating configuration into a simple basic interface (</span><span style="font-family: Courier New, Courier, monospace;">PropertyMap</span><span style="font-family: Arial, Helvetica, sans-serif;">) and a more complex extended variant (</span><span style="font-family: Courier New, Courier, monospace;">Configuration</span><span style="font-family: Arial, Helvetica, sans-serif;">), allows us to easily build composite configurations by combining more simpler partial property maps. Most commonly configuration locations, formats and combination strategies can also provided easily by according factory classes. Also in most cases, implementing the more simpler </span><span style="font-family: 'Courier New', Courier, monospace;">PropertyMap</span><span style="font-family: Arial, Helvetica, sans-serif;">interface should completely sufficient.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Putting all this to reality, we have defined a quite powerful mechanism, that allows us to implement also complex use cases with only a few abstractions.</span></div>
<div style="font-family: Arial, Helvetica, sans-serif;">
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com0tag:blogger.com,1999:blog-6710986841844568686.post-7441454106236846932014-03-20T03:25:00.005-07:002014-04-15T15:09:02.822-07:00Adding Additional Type Support to Configuration<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">Adding Additional Type Support to Configuration </span></h2>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">In my previous blog I discussed roughly what configuration is. I also stopped on a working assumption that configuration mainly is a Map<String,String> type with additional metadata. In this blog I would like to elaborate, how non literal types can be supported. Summarizing I would define the following requirements:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">it should be possible to access configuration as non literal type</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">all types contained in </span><span style="font-family: Courier New, Courier, monospace;">java.lang</span><span style="font-family: Arial, Helvetica, sans-serif;"> should be supported.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">nevertheless arbitrary other types should also be enabled</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">it should be possible to register <i>"converters"</i></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">it should also be possible to pass a matching <i>"converter" </i>programmatically</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">First of all we have to think about, what kind of functionality we want to add here to the basic </span><span style="font-family: Courier New, Courier, monospace;">Configuration </span><span style="font-family: Arial, Helvetica, sans-serif;">interface (this is also the reason why converter is written in <i>italic </i>face above).</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically adding type support requires a configuration entry's value, that is a </span><span style="font-family: Courier New, Courier, monospace;">String </span><span style="font-family: Arial, Helvetica, sans-serif;">to be compatible with some arbitrary type:</span></div>
<blockquote class="tr_bq">
<span style="font-family: Trebuchet MS, sans-serif;"><span style="background-color: white; line-height: 19.200000762939453px;"> "...allows the </span><a class="mw-redirect" href="http://en.wikipedia.org/wiki/Interface_(computer_science)" style="background-color: white; background-image: none; color: #0b0080; line-height: 19.200000762939453px; text-decoration: none;" title="Interface (computer science)">interface</a><span style="background-color: white; line-height: 19.200000762939453px;"> of an existing </span><a class="mw-redirect" href="http://en.wikipedia.org/wiki/Class_(computer_science)" style="background-color: white; background-image: none; color: #0b0080; line-height: 19.200000762939453px; text-decoration: none;" title="Class (computer science)">class</a><span style="background-color: white; line-height: 19.200000762939453px;"> to be used from another interface."</span></span></blockquote>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">This is exactly the GoF's adapter pattern. So let as define an adapter:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">@FunctionalInterface</span></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span style="color: #990000;"><b>public interface</b> </span>PropertyAdapter<T>{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <T> T adapt(String value);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br />Now we can extend </span><span style="font-family: Courier New, Courier, monospace;">Configuration </span><span style="font-family: Arial, Helvetica, sans-serif;">to allow access on configuration using such an adapter:</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span style="color: #990000;"><b>public interface </b></span>Configuration{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <T> T getAdapted(String key, PropertyAdapter<T> adapter);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Obviously this is a very minimalistic approach. Now thinking on all basic types defined in <span style="font-family: "Courier New",Courier,monospace;">java.lang</span>, it is a good idea to add corresponding convenience methods:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div>
<span style="font-family: Courier New, Courier, monospace;"><span style="color: #990000;"><b>public interface </b></span>Configuration{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Character getCharacter(String key);</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Byte getByte(String key);</span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Short getShort(String key);</span></span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Integer getInteger(String key);</span></span></span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Long getLong(String key);</span></span></span></span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Float getFloat(String key);</span></span></span></span></span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Double </span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">getDouble(String key);</span> </span> </span> </span> </span></span> </span></span></span></span></span> </span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">By default, I would suggest throwing a <span style="font-family: "Courier New",Courier,monospace;">RuntimeException</span>, if a value is missing, is a good idea, so these methods never will return <span style="font-family: "Courier New",Courier,monospace;">null </span>values. Additinoally it might b e a good idea to let also default values to be returned, so we add also the following methods:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<br />
<span style="font-family: Courier New, Courier, monospace;"> Character getCharacter</span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">OrDefault</span></span>(String key, <br /> </span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">Character defaultValue</span>);</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Byte getByteOrDefault(String key</span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">, </span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">Byte </span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">defaultValue</span></span></span></span></span></span></span>);</span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Short getShort</span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">OrDefault</span></span>(String key</span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">, </span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">Short </span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">defaultValue</span></span>);</span></span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Integer getInteger</span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">OrDefault</span></span>(String key</span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">, </span></span></span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">Integer </span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">defaultValue</span></span></span></span></span>);</span></span></span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Long getLong</span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">OrDefault</span></span>(String key</span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">, </span></span></span></span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">Long </span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">defaultValue</span></span></span></span></span>);</span></span></span></span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Float getFloat</span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">OrDefault</span></span>(String key</span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">, </span></span></span></span></span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">Float </span></span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">defaultValue</span></span></span></span></span>);</span></span></span></span></span></span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> Double </span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">getDouble</span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">OrDefault</span></span>(String key</span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">, </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">Double </span></span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">defaultValue</span></span></span></span></span>);</span></span></span></span></span></span></span></span></span></span></span></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"> <T> T getAdapted</span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">OrDefault</span></span>(String key, Adapter<T> adapter</span></span></span></span></span></span></span></span></span></span></span></span></span><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">, <br /> T defaultValue</span></span></span></span></span></span></span></span></span></span></span></span></span>);</span> </span> </span></span></span></span></span></span></span></span></span></span></span><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">With the above signatures passing <span style="font-family: "Courier New",Courier,monospace;">null </span>as a default value is completely valid. So one might write:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;">Byte myNumber = config.getByte("minNumber", </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>null</b></span></span>);</span><br />
<span style="font-family: "Courier New",Courier,monospace;">if(myNumber==null){</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> // do whatever needed</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-family: "Courier New",Courier,monospace;">}</span></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Though such code above is quite common, it might be worthwil to think on additional utility functionality, e.g. using JDK 8 features:</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">Configurator configurator = Configurator.of(config);</span> <br />
<span style="font-family: "Courier New",Courier,monospace;">configurator.forByte("minNumber", <i>MyNumbers::configure</i>};</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Though it would be interesting to investigate this area more, I would like to go one step back and ask, if a single </span><span style="font-family: Courier New, Courier, monospace;">String <span style="font-family: Arial,Helvetica,sans-serif;">configuration </span></span><span style="font-family: Arial, Helvetica, sans-serif;">value is always enough to create/implement every type of adapted interface. We have seen that a configuration entry is basically</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">a configuration key</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">a configuration value</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">configuration entry metadata</span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So to cover that we would extend our interface slightly as follows:</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">@FunctionalInterface</span></span><br />
<div>
<span style="font-family: Courier New, Courier, monospace;"><span style="color: #990000;"><b>public interface</b> </span>PropertyAdapter<T>{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <T> T adapt(String key, String value, <br /> Map<String,String> metadata);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">But this is still not optimal, we would be much more flexible by passing the <span style="font-family: "Courier New",Courier,monospace;">Configuration </span>instance, on which the adapter is used, to the adapter implementation:</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">@FunctionalInterface</span></span><br />
<div>
<span style="font-family: Courier New, Courier, monospace;"><span style="color: #990000;"><b>public interface</b> </span>PropertyAdapter<T>{</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> <T> T adapt(String key, Configuration config);</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">More generally the above is simply a specialization of a query against a configuration, but just for one specific key:</span><br />
<br />
<pre><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">@FunctionalInterface</span></span></pre>
<pre><span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;"><b>public interface</b> ConfigurationQuery<T> {
T queryFrom(Configuration config);
}</span></span></pre>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">Now these concepts can be useful, when thinking on collection support. Image the following configuration:</span></div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">foo.a=aValue</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">foo</span>.b=bValue</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span style="font-family: Courier New, Courier, monospace;">foo</span>.c=cValue</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Given this configuration <span style="font-family: "Courier New",Courier,monospace;">foo </span>can be adapted in different ways:</span><br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">It can be adapted to a <span style="font-family: "Courier New",Courier,monospace;">Map </span>with <span style="font-family: "Courier New",Courier,monospace;">a=aValue, b=bValue, c=cValue</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">But it can also be mapped to a <span style="font-family: "Courier New",Courier,monospace;">List </span>(interpreting <span style="font-family: "Courier New",Courier,monospace;">a,b,c</span> as ordering predicate) with <span style="font-family: "Courier New",Courier,monospace;">aValue, bValue, cValue</span>.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Similarly it could also be mapped to a tree:<br /><span style="font-family: "Courier New",Courier,monospace;"> (root)<br /> / | <span style="font-family: Arial, Helvetica, sans-serif;"></span>\ <br /> a b c<br /> | | | <br /> aValue bValue cValue</span></span></li>
</ul>
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">With the extended adapter definition all that is possible.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<span style="font-family: Arial, Helvetica, sans-serif;">With that our <span style="font-family: "Courier New",Courier,monospace;">Configuration </span>is already very flexible, for example think on the following entry:</span><span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">javax.persistence.unit.MyUnit=https://myconfigserver.net/myApp/persistence/MyUnit.xml?myinstance=${instance.host}</span><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small;"> </span></span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small;">This e</span>ntry could reference a <span style="font-family: "Courier New",Courier,monospace;">persistence.xml,</span> that is provided remotely. With </span><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-family: "Courier New",Courier,monospace;">${instance.host}</span> EL could be used to enable also dynamic aspects included into the configuration.</span><br />
<span style="font-family: Arial,Helvetica,sans-serif;">Now an adapter might return a <span style="font-family: "Courier New",Courier,monospace;">String</span>, containing the descriptor file, but this would load the configuration completely into memory. As an alternate we might allow to return an </span><span style="font-family: "Courier New",Courier,monospace;">InputStream</span>:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">InputStream myUnitConfigStream = config.getAdapted(<br /> "javax.persistence.unit.MyUnit",</span><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-family: "Courier New",Courier,monospace;"><br /> URLResolver.of());</span></span><br />
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-family: "Courier New",Courier,monospace;">URLResolver </span>would implements hereby an adapter that creates an URL and tries to load it, returning the <span style="font-family: "Courier New",Courier,monospace;">InputStream</span>. It is accessed using a static factory method:</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>public final class</b></span> URLResolver <span style="color: #990000;"><b>implements</b></span> PropertyAdapter<InputStream>{</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"> <span style="color: #990000;"><b>private static final </b></span></span><span style="font-family: "Courier New",Courier,monospace;">URLResolver INSTANCE = <span style="color: #990000;"><b>new </b></span></span><span style="font-family: "Courier New",Courier,monospace;">URLResolver(); <span style="color: #990000;"></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /> <span style="color: #990000;"><b>private </b></span>URLResolver(){}</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>public </b></span></span>InputStream adapt(String key, Configuration config){</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <b><span style="color: #990000;">try</span></b>{</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> URL url = new URL(config.getValueOrDefault(key, <span style="color: #990000;"><b>null</b></span>));</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> if(url!=null){</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <span style="color: #990000;"><b>return </b></span>url.openStream();<br /> }</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> } </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <span style="color: #990000;"><b>catch </b></span>(Exception e){</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> <span style="color: #666666;">// log error</span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"></span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>return </b></span></span></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>null</b></span></span></b></span></span>;</span> </span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }</span><br />
<span style="font-family: "Courier New",Courier,monospace;"><br /></span>
<span style="font-family: "Courier New",Courier,monospace;"> <span style="color: #990000;"><b>public static </b></span>URLResolver of(){</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> </span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b>return </b></span></span></span><span style="font-family: "Courier New",Courier,monospace;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"><b><span style="font-family: "Courier New",Courier,monospace;"><span style="color: #990000;"></span></span></b></span></span></span></span>INSTANCE;</span><br />
<span style="font-family: "Courier New",Courier,monospace;"> }</span><br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">}</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">So we have seen that with rather small additional to the Configuration interface, we already have gained much flexibility, what we can do with it. Thinking on the new features of Java 8 configuration will be for sure get much more fun than it was in the past.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;">I would be interested, on what you think would be useful scenarios, using the mechanism presented in this blog. So you are invited to leave your comments and ideas!</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com0tag:blogger.com,1999:blog-6710986841844568686.post-83898562629129658372014-03-10T04:08:00.000-07:002014-04-15T15:09:13.317-07:00The Complexities of Configuration<h2>
<span style="font-family: Arial, Helvetica, sans-serif;">The Complexities of Configuration</span></h2>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">In this blog I start to write some blogs about configuration. I will start rather general and then dive deeper into several topics as useful. I do not reclaim scientific correctness, so be polite with me, if I miss a point. Nevertheless I think, and hope somebody else finds it interesting. Feedback of any kind is always welcome, so we can have also some kind of two way communications here...</span></div>
<div>
<br /></div>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Understanding Configuration</span></h3>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">General Aspects</span></h4>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Basically one might ask, what configuration is at all. When looking at the a computation model, where some input is converted to some output, configuration can be seen as some kind of control flow, which affects the transformation. Nevertheless configuration is not equal to the program converting input to output. Configuration is more like a constraint recipe that tells the program in place, what to do, but only within the boundaries of the program allows to be configured. Obviously, if the configuration is so powerful, that it is capable of performing any task, it is questionable, if this should be called configuration (it may be called more a <i>script or recipe</i>). </span></div>
<div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">So summarizing configuration</span></div>
<div>
<ul>
<li><span style="background-color: white;"><span style="font-family: Arial, Helvetica, sans-serif;">should be constrained and limited for purpose.</span></span></li>
<li><span style="background-color: white;"><span style="font-family: Arial, Helvetica, sans-serif;">must be interpreted by some algorithmic logic</span></span></li>
</ul>
</div>
</div>
<div>
<div>
<div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Configuration is an API</span></h4>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Configuration is not there just for fun. With configuration your program logic defines an API, which clients interacts with. If you change it, you will break the contract. If you replace configuration, you must deprecated it. But things get worse. With code you have a compiler that flags out deprecations and will fail if pieces do not fit together anymore. With configuration you do not have any such tools.</span></div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">As a consequence, like with APIs, you must think on what should be configurable. In general, similar as when designing programmatic APIs, reduce your API footprint to an absolute minimum. Frankly speaking, if something is not really meant to be configured or very complex to configure, or even very rarely used, consider to make it non configurable at all. Instead of ensure the component is well encapsulated as a Java artifact, so customers still can replace it with their own version if needed.</span></div>
</div>
<div>
<h4>
<b><span style="font-family: Arial, Helvetica, sans-serif;">Configuration Types</span></b></h4>
<h3>
<div style="font-size: medium; font-weight: normal;">
</div>
<div style="font-size: medium; font-weight: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">When thinking on configuration types there are a couple of things that are commonly used to "configure" a program:</span></div>
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">command line arguments</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">environment properties</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">system properties</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">files and classpath resources, using different formats; including standardized deployment descriptors as well as vendor specific formats</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">databases</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">remote configuration services</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">...</span></span></li>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">This is list is for sure far from being complete. Nevertheless there are some similarities in most cases you will find:</span></span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">a configuration entry is identified by some literal <i>key.</i></span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">configuration values most of the times are <i>literal values. </i>As a consequence configuration can basically be mapped to <i>key/value pairs</i>.</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">configuration most of the time is </span>single valued<span style="font-weight: normal;">, but sometimes also </span>multi valued<span style="font-weight: normal;"> (e.g. collections).</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">often keys use a naming scheme similar to package and class names (though property names are typically in lower case), e.g. a.b.c.myvalue. Hereby myvalue can be defined as the parameter <i>name</i> and a.b.c can be named the parameter <i>area</i>.</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">theoretically configuration values (as well as keys) may be of any type. Nevertheless if we would not constrain anything, we are again struggling with complexity and overlapping functionalities with other standards, e.g. CDI, are the natural consequence.</span></span></li>
</ul>
</div>
</h3>
<h4>
<b><span style="font-family: Arial, Helvetica, sans-serif;">Configuration Building Blocks</span></b></h4>
<h3>
<div>
</div>
</h3>
<h3>
<div style="font-size: medium; font-weight: normal;">
</div>
<div style="font-size: medium; font-weight: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">So given the list above configuration is not a monolithic thing. It is a composite of</span></div>
<br />
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">different configuration providers</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">different configuration sources</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">Override and priority rules for resolution of ambigous entries</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">Filters and views for limiting access and ensure only the information required is visible</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">finally composition can be made in different ways:</span></span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">unions, rendering redundant entries to according multi-value entries.</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">resolving unions, where overriding and prioritization mechanism resolve the entries are visible in the composite configuration</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">extending, where only additional entries not contained in the base configuration are added, but the (redundant ones) are ignored.</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">exclusive add, where only entries were taken up into the composite that are contained only in either of the base configurations, but never in both.</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">subtractive, where you will remove the entries from the base configuration, that are contained in the second configuration</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">...</span></span></li>
</ul>
</ul>
<div>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">Additionally configuration</span></span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">may be static</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">may be different depending on the current runtime environment</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">or even mutable to some extend (or at least updateable). I will cover this topic in a separate blog, since mutability of configuration implies a bunch of possible issues you may face, especially when running in a EE environment, where concurrency is a default case!</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">maybe public or may contain entries to be protected by security mechanism</span></span></li>
</ul>
</div>
</h3>
<h4>
<b><span style="font-family: Arial, Helvetica, sans-serif;">Configuration Metadata</span></b></h4>
<h3>
<div>
<div style="font-size: medium; font-weight: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">Configuration meta data allows to store and provide additional data that describes configuration. It can be scoped on:</span></div>
</div>
</h3>
<h3>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">to a compete configuration</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">a partial configuration</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">a single configuration entry</span></span></li>
</ul>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">Possible meta data could be:</span></span><ul>
<li><span style="font-size: small; font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;">the data provider</span></span></li>
<li><span style="font-size: small; font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;">any additional provider settings</span></span></li>
<li><span style="font-size: small; font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;">the type of data source</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small; font-weight: normal;">the configuration</span><span style="font-size: small; font-weight: normal;"> </span><span style="font-size: small; font-weight: normal;">data's sensitivity</span></span></li>
<li><span style="font-size: small; font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;">the configuration data owner</span></span></li>
<li><span style="font-size: small; font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;">the exact source of the data, e.g. the jar and file path, where a classpath resource was loaded from.</span></span></li>
</ul>
</h3>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif; font-size: small;">Configuration Model</span></h4>
<h3>
<div style="font-size: medium; font-weight: normal;">
<span style="font-size: small;"><span style="font-family: Arial, Helvetica, sans-serif;">So given the points above I will stick to the working assumption to constrain a</span> </span><span style="font-family: 'Courier New', Courier, monospace;">Configuration </span><span style="font-size: small;"><span style="font-family: Arial, Helvetica, sans-serif;">to be nothing else than a</span> <span style="font-family: Courier New, Courier, monospace;">Map<String,String></span><span style="font-family: Arial, Helvetica, sans-serif;"> instance, with some additional metadata and an identifier, that identifies a </span><span style="font-family: Courier New, Courier, monospace;">Configuration:</span></span></div>
<div style="font-size: medium; font-weight: normal;">
<span style="font-size: small;"><span style="font-family: Courier New, Courier, monospace;"><br /></span></span></div>
<div>
<span style="font-size: small;"></span><br />
<div style="font-family: 'Courier New', Courier, monospace;">
<span style="font-size: small;"><span style="color: #990000;">public interface</span><span style="font-weight: normal;"> Configuration </span><span style="color: #990000;">extends </span><span style="font-weight: normal;">Map<String,String>{</span></span></div>
<span style="font-size: small;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">
<br /></div>
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">
/**</div>
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">
* Access the identifying key of a configuration.</div>
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">
* @return the configuration's key</div>
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">
*/</div>
<div style="font-family: 'Courier New', Courier, monospace;">
<span style="font-weight: normal;"> </span><span style="color: #990000;">public </span><span style="font-weight: normal;">ConfigId getConfigId();</span></div>
<div style="font-family: 'Courier New', Courier, monospace;">
<div>
<span style="font-weight: normal;"><br /></span></div>
<div>
<span style="font-weight: normal;"> /**</span></div>
<div>
<span style="font-weight: normal;"> * Get the meta information for the given key.</span></div>
<div>
<span style="font-weight: normal;"> *</span></div>
<div>
<span style="font-weight: normal;"> * @param key the key, not {@code null}.</span></div>
<div>
<span style="font-weight: normal;"> * @return the according meta-info, or {@code null}.</span></div>
<div>
<span style="font-weight: normal;"> */</span></div>
<div>
<span style="font-weight: normal;"> </span><span style="color: #990000;">public </span><span style="font-weight: normal;">Map<String,String> getMetaInfo(String key);</span></div>
<div>
<span style="font-weight: normal;"><br /></span></div>
<div>
<span style="font-weight: normal;"> /**</span></div>
<div>
<span style="font-weight: normal;"> * This method allows to check, if an instance is mutable. If <br /> * an instance is not mutable most of the so called</span></div>
<div>
<span style="font-weight: normal;"> * <i>optional</i> method of {@link java.util.Map} will throw <br /> * an {@link java.lang.UnsupportedOperationException}:</span></div>
<div>
<span style="font-weight: normal;"> * <ul></span></div>
<div>
<span style="font-weight: normal;"> * <li>{@link #put(Object, Object)}</li></span></div>
<div>
<span style="font-weight: normal;"> * <li>{@link #putAll(java.util.Map)}</li></span></div>
<div>
<span style="font-weight: normal;"> * <li>{@link #clear()}</li></span></div>
<div>
<span style="font-weight: normal;"> * <li>{@link #putIfAbsent(Object, Object)}</li></span></div>
<div>
<span style="font-weight: normal;"> * <li>{@link #remove(Object)}</li></span></div>
<div>
<span style="font-weight: normal;"> * <li>{@link #remove(Object, Object)}</li></span></div>
<div>
<span style="font-weight: normal;"> * <li>{@link #replace(Object, Object)}</li></span></div>
<div>
<span style="font-weight: normal;"> * <li>{@link #replace(Object, Object, Object)}</li></span></div>
<div>
<span style="font-weight: normal;"> * <li>{@link #replaceAll(java.util.function.BiFunction)}<br /> * </li></span></div>
<div>
<span style="font-weight: normal;"> * </ul></span></div>
<div>
<span style="font-weight: normal;"> * @return true, if this instance is mutable.</span></div>
<div>
<span style="font-weight: normal;"> */</span></div>
<div>
<span style="font-weight: normal;"> </span><span style="color: #990000;">public boolean </span><span style="font-weight: normal;">isMutable();</span></div>
</div>
<div style="font-family: 'Courier New', Courier, monospace;">
<span style="font-weight: normal;">}</span></div>
<div style="font-family: 'Courier New', Courier, monospace;">
<br /></div>
<div style="font-weight: normal;">
I am well aware that this looks quite simple, so I will refine this model in subsequent blogs for covering additional requirements with things like</div>
<div>
<ul>
<li><span style="font-weight: normal;">extension points like queries and type adapters</span></li>
<li><span style="font-weight: normal;">Adding basic type support for JDK's standard types (boolean, characters, numbers)</span></li>
<li><span style="font-weight: normal;">enabling submodules</span></li>
<li><span style="font-weight: normal;">and more...</span></li>
</ul>
</div>
</span></div>
</h3>
<h3>
<div style="font-size: medium; font-weight: normal;">
</div>
</h3>
<h3>
Configuration Locations</h3>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Separate Configuration from Code</span></h4>
<h3>
<div style="font-size: medium; font-weight: normal;">
<div>
</div>
</div>
</h3>
<h3>
<div style="font-size: medium; font-weight: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">An area of discussion is sometimes if configuration must be strictly separated from code. I will not join any of the sometimes religious discussion on that, but define some rules of thumb, when I think configuration should be separated and when it should be deployed along the code. </span></div>
<div style="font-size: medium; font-weight: normal;">
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Configuration that is <i>internal only</i>, meaning it is not meant being used by clients, should always deployed with the code, basically within the same jar, if possible. This makes sense since such configuration is highly coupled to the code.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><i>Default</i> configuration that may be overridden, should still be deployed along the code. This ensures the defaults are always visible, when the code is deployed (with an according configuration reading mechanism in place, e.g. that honors the same classloading boundaries). Also it is a precondition to let <i>convention-over-configuration</i> to work effectively.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">In next step I would think of configuration that controls the overall basic deployment setup, but still targets rather general concerns. For example configuration defining which modules are loaded, depending on the current deployment stage is such a case. Such configuration, though it may be stage specific, will not be affected by changes within the current runtime environment. I would recommend to deploy such configuration also with the application, e.g. as part of the deployed ear or war-archives. Reason is, that I tend to see configuration also as a n (optionally stage specific) <i>default </i>configuration.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Finally there is configuration that targets direct deployment aspects and that may change for each single deployment, regardless if performed manually or in an automated cloud like environment. This configuration should be separated from the code, meaning independently deployed. Hereby there are several options how to achieve this:</span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Deploy the files required with <i>ssh, sftp</i> or similar to the target node, where it can be read.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Mount some specific area into the file system, where the files are locally visible, e.g. <i>nfs </i>etc.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Access configuration from a configuration server (<i>Pull</i>-scenario).</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Open a connection and wait, for the configuration server to push the configuration required onto your node (<i>push</i>-scenario).</span></li>
</ul>
</ul>
</div>
</h3>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Add Configuration as Classpath Resources</span></h4>
<h3>
<div style="font-size: medium; font-weight: normal;">
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Many people tend to see configuration as files that must be deployed to the target system. Nevertheless in case of internal and default configuration (refer to the previous section for more details), deploying this configuration type as files in a separate deployment channel also creates some possible issues:</span></div>
</div>
</h3>
<h3>
<div style="font-size: medium; font-weight: normal;">
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;"> It is cumbersome if clients have to care about what additional configuration must be installed to get things running. They want to define the dependency on the library and start working with it. In practice this may be even worse, when different versions of the classes require different (default) configuration. Often then outdated configuration is then shipped with newer version of the component, which often end up in hard to find errors.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Also on the deployment side (DevOps) it makes the deployment bigger (more files to be deployed) and more complex, for configuration updates.</span></li>
</ul>
</div>
<div style="font-size: medium; font-weight: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">Whereas when configuration is deployed as classpath resources there are some real benefits:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">The classloader hierarchy ensures the configuration is only visible, where it should be visible. There is less risk, that configuration from different deplyment levels (= class loaders) is mixed up.</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">Reading classpath resources is standard mechanism of the JDK, it is also possibly during very early points of server startup or logging initialization.</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">Reading classpath resources is relatively fast and also can be secured, if necessary.</span></span></li>
</ul>
</div>
<div style="font-size: medium; font-weight: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">But deploying configuration as classpath resources also has some disadvantages:</span></div>
<div style="font-size: medium; font-weight: normal;">
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">First of all, it is less transparent. Theoretically each jar in a 200 jar deployment can contain relevant configuration. To find all the relevant entries maybe very difficult, especially if no common configuration lookup mechanism is defined and each code, is looking up configuration at arbitrary locations.</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">Overriding may also be more complex. You can override a file deployed to some file system easily, whereas changing a file contained in a jar, basically requires exchanging the whole jar (we ignore other possibilities here).</span></li>
</ul>
</div>
</h3>
<h3>
<div style="font-size: medium; font-weight: normal;">
<div>
</div>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Fortunately the disadvantages can be handled relatively easily by externalizing the concern of configuration reading and management into a dedicated configuration service. </span></div>
<div>
<br /></div>
</div>
</h3>
<h3>
<span style="font-family: Arial, Helvetica, sans-serif;">Using a Configuration Service</span></h3>
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">If you would let each code individually lookup the configuration you may end up in systems that hard to control because</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;">you will have to know which code is reading and using which configuration, and have to look into the source code to see what is happening</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">configuration locations are scattered across your system</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;">you will probably have to deal with several different formats</span></li>
</ul>
</div>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Core Functionality</span></h4>
<h3>
<div style="font-size: medium; font-weight: normal;">
<div>
<span style="font-family: Arial, Helvetica, sans-serif;">Using a dedicated configuration service for reading and managing configuration has several advantages:</span></div>
</div>
<div>
<ul>
<li style="font-size: medium; font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;">It allows to define a (or several) configuration meta model, defining</span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small; font-weight: normal;">where configuration is </span><span style="font-size: small; font-weight: normal;">located </span><span style="font-size: small; font-weight: normal;">(CLI arguments, system properties, environment properties, classpath, filesystem, remote resources etc).</span></span></li>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size: small; font-weight: normal;">how configuration can be </span><span style="font-size: small;"><span style="font-weight: normal;">overridden (ordering of declarations, explicit priorities and overrides etc).</span></span></span></li>
<li style="font-size: medium;"><span style="font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;">in what format configuration must be provided (properties, XML, JSON, ...)</span></span></li>
</ul>
<li style="font-size: medium;"><span style="font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;">manage the configuration read, depending on the current runtime environment and</span></span></li>
<li style="font-size: medium;"><span style="font-weight: normal;"><span style="font-family: Arial, Helvetica, sans-serif;">optimize configuration access, e.g. by caching or preloading.</span></span></li>
<li style="font-size: medium;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-weight: normal;">provide hooks for listening to configuration changes</span> <span style="font-weight: normal;">(new configuration added, configuration altered or deleted)</span></span></li>
<li style="font-size: medium;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-weight: normal;">also such s service can provide additional</span> <span style="font-weight: normal;">meta data about configuration and configuration entries.</span></span></li>
</ul>
</div>
</h3>
<h4>
<span style="font-family: Arial, Helvetica, sans-serif;">Extended Functionality</span></h4>
<h3>
<div style="font-size: medium; font-weight: normal;">
<span style="font-family: Arial, Helvetica, sans-serif;">As a benefit, since a configuration service controls everything happening in the area of configuration, it can provide additional services:</span></div>
<div>
<ul>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">It can intercept configuration access to ensure security constraints</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">It can configuration access to log which code is using what kind of configuration. This can also easily be used of configuration evolution, e.g. by writing warning messages when deprecated parameters are read.</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">It can include additional configuration sources and locations to a configuration transparently, without having to change any client code.</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">a configuration service can be made remotely accessible, so it acts as a configuration server (pull scenario), or</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">it can be triggered, so it pushes configuration changes, to the according remote instances (push scenario)</span></span></li>
<li><span style="font-family: Arial, Helvetica, sans-serif; font-size: small;"><span style="font-weight: normal;">...</span></span></li>
</ul>
</div>
</h3>
<h3>
<b>Configuration Injection</b></h3>
</div>
<span style="font-family: Arial, Helvetica, sans-serif;">We have seen that a configuration service can create huge benefits. Nevertheless we have to be careful. to avoid a hard dependency on the configuration service component. This would happen, if we access all our configuration using a <i>service location pattern</i>, e.g.</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">Configuration config = <br /> ConfigService.getConfiguration(MyConfigs.MainConfig);</span><br />
<span style="font-family: Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Arial, Helvetica, sans-serif;">Fortunately since Java EE 6 we have CDI in place, which allows us to transparently inject things, so we might think of doing thinks as follows:</span><br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><b><span style="color: #990000;">public class</span></b> MyClass{</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #444444;">@Configured</span></span><br />
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #990000;"><b>private </b></span>String userName;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> </span><br />
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="color: #444444; font-family: 'Courier New', Courier, monospace;">@Configured</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #990000;"><b>private int </b></span>userName;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> ...</span><br />
<span style="font-family: Courier New, Courier, monospace;">}</span><br />
<br />
<span style="font-family: Arial, Helvetica, sans-serif;">The code snippet above does only depend on the</span><span style="font-family: Courier New, Courier, monospace;"> @Configure</span>d <span style="font-family: Arial, Helvetica, sans-serif;">annotation. All configuration management logic is completely hidden. Nevertheless the code above looks very compelling it has some severe drawbacks, which we will also discover in later blogs. Do you see them already?</span><br />
<br />
<div>
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/08634170528353247173noreply@blogger.com2