I am looking for a solution for the following problem: I have a complex application consisting of several modules. Each of the modules has its own configuration which is stored in a single XML file. The structure of the XML file is similar to:
When the application is started, the XML file is read and the modules are created using Class.forName. Each of the modules has an init method which takes an XML element and then initializes itself from XML. To make it less cumbersome to write new modules, I introduced a ConfigAttribute annotation. The module base class contains code to automatically init fields marked with @ConfigAttribute from the provided XML element when the init method is called.
This works fine, but this approach also has several problems: 1) The modules directly read and write their configurations. This makes it hard to change the configuration file format e.g. from XML to something else. 2) The reflection code that is used to automatically read the configuration of the modules from XML is not very understandable (it is more complicated then the above example).
1) Could be solved by introducing a config classes which are then passed to the modules after they are created. I think case classes would be perfect as config classes.
What's the best way to solve this kind of problem? Are there any frameworks/libs to do this?
I think this solution may be way more complicated than what you really
need.
Why do you need a configuration file where you specify which modules to
load? You could simply search in the Classpath for compatible modules. I've
been experimenting with this for a small library for doing database
migrations, that searches for available migrations defined, which are plain
classes implementing a certain interface - you can look at the code, it's a
little ugly and may have bugs, but it works [1] [2]
Then if you want to disable modules without pulling them out of the
project, without recompilation, then the configuration should specify which
modules to deactivate.
Then you're injecting values into the module's properties. Personally I
hate dependency-injection as the mechanism for doing IoC and I think it's
just an artifact of broken designs. Your design for passing params is not
statically type-safe anyway, so just pass to the module a dictionary of
keys and values and let it auto-configure itself.
Also, it's easier to work with Json or Yaml, because XML has no structure
and there's nothing you can't specify with a bunch of Maps, Lists and
Strings.
> I am looking for a solution for the following problem: I have a complex
> application consisting of several modules. Each of the modules has its own
> configuration which is stored in a single XML file. The structure of the
> XML file is similar to:
> When the application is started, the XML file is read and the modules are
> created using Class.forName. Each of the modules has an init method which
> takes an XML element and then initializes itself from XML. To make it less
> cumbersome to write new modules, I introduced a ConfigAttribute annotation.
> The module base class contains code to automatically init fields marked
> with @ConfigAttribute from the provided XML element when the init method
> is called.
> This works fine, but this approach also has several problems:
> 1) The modules directly read and write their configurations. This makes it
> hard to change the configuration file format e.g. from XML to something
> else.
> 2) The reflection code that is used to automatically read the
> configuration of the modules from XML is not very understandable (it is
> more complicated then the above example).
> 1) Could be solved by introducing a config classes which are then passed
> to the modules after they are created. I think case classes would be
> perfect as config classes.
> What's the best way to solve this kind of problem? Are there any
> frameworks/libs to do this?
the application is a server application that consists of several modules
which provide different services. The server application is used by several
customers and every customer needs a different set of modules. Some of the
modules are quite complex and there configuration has to be stored somehow.
I know I can work with Maps, Lists etc. but I don't think it is any better
then the approach I use now.
I want to do something like this:
Given a case class
case class Test(value1: Int, value2: String)
I want to be able to write this class to an XML file:
<Test value1="5" value2="Hello">
and read the class from an XML file using a method like
def parse[Test](elem: Element): Test
I guess I could do this using reflection. But I would prefer to use an
existing solution if there is one. The other problem is that case classes
are immutable so I don't know if it is easy to create them from an XML
element using reflection. I could use standard classes, but I think it
would be quite conventient to use case classes.
> I think this solution may be way more complicated than what you really
> need.
> Why do you need a configuration file where you specify which modules to
> load? You could simply search in the Classpath for compatible modules. I've
> been experimenting with this for a small library for doing database
> migrations, that searches for available migrations defined, which are plain
> classes implementing a certain interface - you can look at the code, it's a
> little ugly and may have bugs, but it works [1] [2]
> Then if you want to disable modules without pulling them out of the
> project, without recompilation, then the configuration should specify which
> modules to deactivate.
> Then you're injecting values into the module's properties. Personally I
> hate dependency-injection as the mechanism for doing IoC and I think it's
> just an artifact of broken designs. Your design for passing params is not
> statically type-safe anyway, so just pass to the module a dictionary of
> keys and values and let it auto-configure itself.
> Also, it's easier to work with Json or Yaml, because XML has no structure
> and there's nothing you can't specify with a bunch of Maps, Lists and
> Strings.
sorry, I screwed up the replies a bit. Here it is again:
the application is a server application that consists of several modules
which provide different services. The server application is used by several
customers and every customer needs a different set of modules. Some of the
modules are quite complex and there configuration has to be stored somehow.
I know I can work with Maps, Lists etc. but I don't think it is any better
then the approach I use now.
I want to do something like this:
Given a case class
case class Test(value1: Int, value2: String)
I want to be able to write this class to an XML file:
<Test value1="5" value2="Hello">
and read the class from an XML file using a method like
def parse[Test](elem: Element): Test
I guess I could do this using reflection. But I would prefer to use an
existing solution if there is one. The other problem is that case classes
are immutable so I don't know if it is easy to create them from an XML
element using reflection. I could use standard classes, but I think it
would be quite conventient to use case classes.
> I think this solution may be way more complicated than what you really
> need.
> Why do you need a configuration file where you specify which modules to
> load? You could simply search in the Classpath for compatible modules. I've
> been experimenting with this for a small library for doing database
> migrations, that searches for available migrations defined, which are plain
> classes implementing a certain interface - you can look at the code, it's a
> little ugly and may have bugs, but it works [1] [2]
> Then if you want to disable modules without pulling them out of the
> project, without recompilation, then the configuration should specify which
> modules to deactivate.
> Then you're injecting values into the module's properties. Personally I
> hate dependency-injection as the mechanism for doing IoC and I think it's
> just an artifact of broken designs. Your design for passing params is not
> statically type-safe anyway, so just pass to the module a dictionary of
> keys and values and let it auto-configure itself.
> Also, it's easier to work with Json or Yaml, because XML has no structure
> and there's nothing you can't specify with a bunch of Maps, Lists and
> Strings.
> On Fri, Nov 16, 2012 at 6:56 PM, Michi <
> michael.tha...@physik.tu-muenchen.de> wrote:
>> Hi,
>> I am looking for a solution for the following problem: I have a complex
>> application consisting of several modules. Each of the modules has its own
>> configuration which is stored in a single XML file. The structure of the
>> XML file is similar to:
>> When the application is started, the XML file is read and the modules are
>> created using Class.forName. Each of the modules has an init method which
>> takes an XML element and then initializes itself from XML. To make it less
>> cumbersome to write new modules, I introduced a ConfigAttribute annotation.
>> The module base class contains code to automatically init fields marked
>> with @ConfigAttribute from the provided XML element when the init method
>> is called.
>> This works fine, but this approach also has several problems:
>> 1) The modules directly read and write their configurations. This makes
>> it hard to change the configuration file format e.g. from XML to something
>> else.
>> 2) The reflection code that is used to automatically read the
>> configuration of the modules from XML is not very understandable (it is
>> more complicated then the above example).
>> 1) Could be solved by introducing a config classes which are then passed
>> to the modules after they are created. I think case classes would be
>> perfect as config classes.
>> What's the best way to solve this kind of problem? Are there any
>> frameworks/libs to do this?