NanoContainer
  1. NanoContainer
  2. NANO-157

Modifiable/Overridable ScriptedContainerBuilderFactory

    Details

    • Type: New Feature New Feature
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.0
    • Component/s: core
    • Labels:
      None
    • Testcase included:
      yes
    • Number of attachments :
      2

      Description

      I had mentioned on the mail list that I needed to have my own builders that didn't autostart pico like the default implementation did. The problem is that I wanted to be able to use deployer which uses the ScriptedContainerBuilderFactory to resolve the composition script extension to the builder.

      So I've modified ScriptedContainerBuilderFactory to allow for registration/override of new handlers. I tried to make it thread-safe since esp in a web environment, who knows what order bootstrap code might well be called, and added reset and query capabilities for better testability.

      HTH!
      -Mike

        Activity

        Hide
        Michael Rimov added a comment -

        New CustomGroovyNodeBuilder is now the default node builder.

        Show
        Michael Rimov added a comment - New CustomGroovyNodeBuilder is now the default node builder.
        Michael Rimov made changes -
        Field Original Value New Value
        Fix Version/s 1.0-RC2 [ 11851 ]
        Status Open [ 1 ] Closed [ 6 ]
        Resolution Fixed [ 1 ]
        Assignee Michael Rimov [ rimovm ]
        Hide
        Michael Rimov added a comment -

        Whoops – wrong issue I commented on last time. Patch is applied and committed.

        Show
        Michael Rimov added a comment - Whoops – wrong issue I commented on last time. Patch is applied and committed.
        Hide
        Michael Rimov added a comment -

        I am refactoring my patch as I realized it was MUCH too 'static'y.

        Show
        Michael Rimov added a comment - I am refactoring my patch as I realized it was MUCH too 'static'y.
        Michael Rimov made changes -
        Status Closed [ 6 ] Reopened [ 4 ]
        Resolution Fixed [ 1 ]
        Hide
        Michael Rimov added a comment -

        Hi All,

        I've got a problem. I seem to be stuck between two issues to get what I want. The solution I checked into SVN to resolve what I need has zero behavior differences. But it uses statics, and of course, the whole point is to try to avoid that.

        But that means (to me) changing the constructor so I can delay instantiation of the ScriptedBuilderFactory. But that changes the behavior of the class like so:

        try

        { //Old behavior -- ClassNotFoundException could be thrown here. //New Behavior -- No chance of error occuring. factory = new ScriptedContainerBuilderFactory(new File("myfile.groovy")) }

        catch (ClassNotFoundException ex)

        { handleError(ex); }

        //Old Behavior – No Chance of error occuring on function call.
        //New Behavior – BuilderClassNotFoundException could be thrown here.
        ScriptedContainerBuilder builder = factory.getContainerBuilder();

        So somebody that wrote code like that above could have their code fail on them suddenly when they thought they had it all taken care of. (Its a rare case, mind you!)

        So I've included a patch with the new code so you can examine it. Is this change in behavior ok for Pico standards? (All current test cases pass fine)

        Thanks for taking a look!

        Show
        Michael Rimov added a comment - Hi All, I've got a problem. I seem to be stuck between two issues to get what I want. The solution I checked into SVN to resolve what I need has zero behavior differences. But it uses statics, and of course, the whole point is to try to avoid that. But that means (to me) changing the constructor so I can delay instantiation of the ScriptedBuilderFactory. But that changes the behavior of the class like so: try { //Old behavior -- ClassNotFoundException could be thrown here. //New Behavior -- No chance of error occuring. factory = new ScriptedContainerBuilderFactory(new File("myfile.groovy")) } catch (ClassNotFoundException ex) { handleError(ex); } //Old Behavior – No Chance of error occuring on function call. //New Behavior – BuilderClassNotFoundException could be thrown here. ScriptedContainerBuilder builder = factory.getContainerBuilder(); So somebody that wrote code like that above could have their code fail on them suddenly when they thought they had it all taken care of. (Its a rare case, mind you!) So I've included a patch with the new code so you can examine it. Is this change in behavior ok for Pico standards? (All current test cases pass fine) Thanks for taking a look!
        Michael Rimov made changes -
        Attachment scriptedcontainerbuilderpatch.zip [ 18012 ]
        Hide
        Mauro Talevi added a comment -

        Can't see much wrong in moving away from static.
        New staticless doesn't seem to me a source of problems either.
        I would +1 unless someone can state a reason for keeping static.

        Show
        Mauro Talevi added a comment - Can't see much wrong in moving away from static. New staticless doesn't seem to me a source of problems either. I would +1 unless someone can state a reason for keeping static.
        Hide
        Jörg Schaible added a comment -

        With lazy initialization we have more code, that might fail at runtime (e.g. the pool is exhausted, the connection to the EJB failed). Therefore I'm fine with less statics.

        Show
        Jörg Schaible added a comment - With lazy initialization we have more code, that might fail at runtime (e.g. the pool is exhausted, the connection to the EJB failed). Therefore I'm fine with less statics.
        Mauro Talevi made changes -
        Fix Version/s 1.0 [ 10148 ]
        Fix Version/s 1.0-RC2 [ 11851 ]
        Hide
        Michael Rimov added a comment -

        Well, after begging and pleading with Mauro and Paul to let me take another crack at this, I undid my previous commit and took another shot at it. This time, I moved the code that Deployer relied on as a static factory into a new class called ScriptBuilderResolver. Using this you can now replace builder implementations for existing types or create new file types through code similar to this:

        ScriptBuilderResolver resolver = new ScriptBuilderResolver();
        resolver.registerBuilder(".groovy", "org.example.MySpecialGroovyBuilder");

        ScriptedContainerBuilderFactory factory = new ScriptedContainerBuilderFactory(new File("MyCustomFile.groovy"), Thread.currentThread().getCustomClassLoader(), resolver);

        ScriptedContainerBuilder builder = factory.getBuilder();
        assert "org.example.MySpecialGroovyBuilder".equals(builder.getClass().getName());

        Example Use Case For This Code:

        I have a custom ComponentAdapter that relies on some other initialization code to occur after composition before becoming fully functional. Unfortunately, the default Groovy builder automatically called PicoContainer.start() on the container thus throwing all sorts of awful exceptions. By creating my own groovy builder that simply didn't call PicoContainer.start() until I was ready for it, problem was solved.

        Final Note:

        This version MUCH more closely matches the behavior in the RC-1 implementation because exceptions are thrown in the constructor like they were before.

        HTH!

        -Mike (R)

        Show
        Michael Rimov added a comment - Well, after begging and pleading with Mauro and Paul to let me take another crack at this, I undid my previous commit and took another shot at it. This time, I moved the code that Deployer relied on as a static factory into a new class called ScriptBuilderResolver. Using this you can now replace builder implementations for existing types or create new file types through code similar to this: ScriptBuilderResolver resolver = new ScriptBuilderResolver(); resolver.registerBuilder(".groovy", "org.example.MySpecialGroovyBuilder"); ScriptedContainerBuilderFactory factory = new ScriptedContainerBuilderFactory(new File("MyCustomFile.groovy"), Thread.currentThread().getCustomClassLoader(), resolver); ScriptedContainerBuilder builder = factory.getBuilder(); assert "org.example.MySpecialGroovyBuilder".equals(builder.getClass().getName()); Example Use Case For This Code: I have a custom ComponentAdapter that relies on some other initialization code to occur after composition before becoming fully functional. Unfortunately, the default Groovy builder automatically called PicoContainer.start() on the container thus throwing all sorts of awful exceptions. By creating my own groovy builder that simply didn't call PicoContainer.start() until I was ready for it, problem was solved. Final Note: This version MUCH more closely matches the behavior in the RC-1 implementation because exceptions are thrown in the constructor like they were before. HTH! -Mike (R)
        Michael Rimov made changes -
        Resolution Fixed [ 1 ]
        Status Reopened [ 4 ] Closed [ 6 ]

          People

          • Assignee:
            Michael Rimov
            Reporter:
            Michael Rimov
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: