How to create modules from a configuration file in a complex application

41 views
Skip to first unread message

Michi

unread,
Nov 16, 2012, 11:56:47 AM11/16/12
to scala...@googlegroups.com
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:

<Application>
  <Module name="module1" class="com.application.ModuleClass1 .../>
  <Module name="module2" class="com.application.ModuleClass2 .../>
  ...
</Application>

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?

Regards,
Michael

Alexandru Nedelcu

unread,
Nov 16, 2012, 12:13:27 PM11/16/12
to Michi, scala-user
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.

[1] https://github.com/alexandru/shifter/blob/master/migrations/src/main/scala/shifter/migrations/MigratorSession.scala#L132
[2] https://github.com/alexandru/shifter/blob/master/core/src/main/scala/shifter/reflection/package.scala
--
Alexandru Nedelcu
http://bionicspirit.com

Michael Thaler

unread,
Nov 16, 2012, 12:49:54 PM11/16/12
to Alexandru Nedelcu, scala-user
Hi Alexandru,

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.

Regards,
Michael


2012/11/16 Alexandru Nedelcu <m...@alexn.org>
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.

[1] https://github.com/alexandru/shifter/blob/master/migrations/src/main/scala/shifter/migrations/MigratorSession.scala#L132
[2] https://github.com/alexandru/shifter/blob/master/core/src/main/scala/shifter/reflection/package.scala

Michael Thaler

unread,
Nov 16, 2012, 12:52:16 PM11/16/12
to Alexandru Nedelcu, scala-user
Hi Alexandru,

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.

Regards,
Michael


2012/11/16 Alexandru Nedelcu <m...@alexn.org>
I think this solution may be way more complicated than what you really need.

ngocdaothanh

unread,
Nov 16, 2012, 3:41:25 PM11/16/12
to scala-user
It's easy if you use JSON:
https://github.com/codahale/jerkson

If you need to use XML, you can produce JSON from XML, then use the
above library.
Reply all
Reply to author
Forward
0 new messages