Search code examples
javaplayframeworkplayframework-2.4playframework-2.5typesafe-config

How to remove an item from list in typesafe config?


In Typesafe configuration there is a very useful operator += which appends a value to an existing list of values. Is there a way to do a reverse, i.e. to remove an item from existing list?

In newer versions of Play Framework (2.4+) += operator is used to tell the dependency injection container which modules are enabled or disabled.

play {
  modules {
    disabled += "play.api.cache.EhCacheModule"
    enabled += "com.github.mumoshu.play2.memcached.MemcachedModule"
  }
}

Typesafe config also supports including configuration files into one another and this is often used to partially override configuration in different environments. Unfortunately Play treats enabled and disabled lists as sets and once a module is added to disabled list there is no way to enable it back. This has been a source of issues and even a special note is given in Play's documentation discouraging use of disabled list.

Note: If you are working on a library, it is highly discouraged to use play.modules.disabled to disable modules, as it can lead to nondeterministic results when modules are loaded by the application (see this issue for reasons on why you should not touch play.modules.disabled). In fact, play.modules.disabled is intended for end users to be able to override what modules are enabled by default.

To be able to conditionally disable modules I came up with an ugly workaround using a feature of typesafe config allowing variable substitutions

In application.conf I have

play {
  modules {
    disabled +=  ${memcached.disabled}"com.github.mumoshu.play2.memcached.MemcachedModule"
  }
}

memcached.disabled = ""

And then in production.conf I put something like this

include "application.conf"

memcached.disabled = "x"
play.modules.disabled += "play.api.cache.EhCacheModule"

so when production.conf is used it mangles the disabling in application.conf. Clearly this is not an acceptable solution.


Solution

  • What about the following configuration:

    application.conf

    play {
      modules {
        enabled += "play.api.cache.EhCacheModule"
      }
    }
    

    production.conf

    include "application.conf"
    
    play {
      modules {
        enabled += "com.github.mumoshu.play2.memcached.MemcachedModule"
        disabled += "play.api.cache.EhCacheModule"
      }
    }