Uploaded image for project: 'Magnolia'
  1. Magnolia
  2. MAGNOLIA-5317

i18nizer: Default values set in a constructor override a previously configured value

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Major Major
    • 5.1
    • 5.1.1
    • i18n

      When a proxied bean sets a default for some field in its constructor, via a setter method (which is often done especially in subclasses that provide some default/specific behavior), the "manually" configured value gets overriden. The call flow goes like this:

      class Obj = {
        Obj() {
         setFoo("default")
        }
        void setFoo(String) {}
      }
      
      obj = new Obj()// sets foo to "default"
      obj.setFoo("my configured value")
      
      d = i18nizer.decorate(obj)
      // proxy creation involves invoking the constructor of d
      assertEquals("my configured value", d.getFoo() // fails, d.getFoo() returns "default"
      

      This is a problem inherent to class-based proxies - the constructor of the generated subclass (the proxy) is called when instanciating it. This inherently invokes the original class' constructor, which calls setFoo() in this example. Since in our case, all methods (thus including setFoo) are decorating and delegate to the original underlying object, this overwrites the configured value.

      One possible pattern against this would be to have a protected constructor which takes the default values as arguments; subclasses which want to set default values for certain properties could have a single public no-arg constructor, which delegates to this super construct with the default values instead of calling the corresponding setters. This has the disadvantage that anything that potentially needs a default value should be exposed in the super constructor; which isn't always practical, since one doesn't always have access to the source code thereof.

      Another possibility to investigate is to see if we could somehow "delay" the delegation/decoration until after the subclass/proxy is instanciated. I'm however not sure how that would play with other things such as init() methods and so on.

      Currently impacted by this : FieldDefinition with transformerClass - see MGNLUI-2102 - and ActionDefinition with implementationClass - see MGNLUI-2117 and MGNLUI-2121

        Acceptance criteria

              gjoseph Magnolia International
              ehechinger Eric Hechinger
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved:

                  Bug DoR
                  Task DoD