groovy
  1. groovy
  2. GROOVY-4975

GroovyScripeEngine fails to properly reload when dependent class is updated

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.8.1
    • Fix Version/s: 2.0.5, 1.8.9
    • Component/s: GroovyScriptEngine
    • Labels:
    • Environment:
      Win 7 64bit, OSX Lion
    • Testcase included:
      yes
    • Number of attachments :
      6

      Description

      Let's say you have 2 scripts : script1 and script2 and they both use class BeanX and they are all loaded via the same GroovyScriptEngine instance. If I modify BeanX, the script that is the first to get loaded and references BeanX will reflect changes made to BeanX, while the other or second script to reference BeanX will fail to reflect changes made to BeanX.

      I'm assuming this is not the proper behavior, although I don't see any test to test for this scenario. If one is using groovy via Groovlets or something like Gaelyk where the assumption is that I can write
      scripts and hot have to constantly restart to have my changes reflected then I would assume the GSE should reload classes and dependent classes regardless of the order in which they are referenced.

      Test attached.

      1. GroovyScriptEngineReloadingSlowTest.groovy
        1 kB
        Frans van Buul
      2. patch4975_main.txt
        0.8 kB
        Frans van Buul
      3. patch4975_test.txt
        5 kB
        Frans van Buul
      4. patch4975_v2.txt
        13 kB
        Frans van Buul
      5. ReloadTest.groovy
        4 kB
        David Smith
      6. ReloadTestJava.java
        6 kB
        David Smith

        Activity

        Hide
        Alessio Stalla added a comment -

        Nope, I ran the test again with 1.8.9-SNAPSHOT from Git and it still fails nondeterministically.

        Show
        Alessio Stalla added a comment - Nope, I ran the test again with 1.8.9-SNAPSHOT from Git and it still fails nondeterministically.
        Hide
        blackdrag blackdrag added a comment -

        full determinism is impossible to achieve. UrlConnection.getLastModified may not know milliseconds, that is why there is this truncation. truncating the modification time means that if your change has been done too fast, it cannot be picked up, since it has the same time as before. So you need 1000 ms minimum delay to ensure the time in last modified is updated properly. But it is actually more, since the OS has a timer with differing resolution. A delay of 1100ms should catch most cases, but that does not guarantee the change will be picked up right away. actually the next possible point of a recompilation is time of last compilation plus 1100 plus minimum recompilation interval.

        Show
        blackdrag blackdrag added a comment - full determinism is impossible to achieve. UrlConnection.getLastModified may not know milliseconds, that is why there is this truncation. truncating the modification time means that if your change has been done too fast, it cannot be picked up, since it has the same time as before. So you need 1000 ms minimum delay to ensure the time in last modified is updated properly. But it is actually more, since the OS has a timer with differing resolution. A delay of 1100ms should catch most cases, but that does not guarantee the change will be picked up right away. actually the next possible point of a recompilation is time of last compilation plus 1100 plus minimum recompilation interval.
        Hide
        Alessio Stalla added a comment -

        Ok, let's step back a bit: I don't have a problem with nondeterminism per se - the problem is that GSE doesn't properly reload dependencies, ever, unless a dependency is found to be modified later than it was compiled (due to nondeterminism). That is, nondeterminism is what makes the test pass sometimes, not fail. If you eliminate nondeterminism (for example, by ensuring that there is a long enough sleep between writing Bean.groovy and loading the scripts for the first time), the test always fails.

        Show
        Alessio Stalla added a comment - Ok, let's step back a bit: I don't have a problem with nondeterminism per se - the problem is that GSE doesn't properly reload dependencies, ever , unless a dependency is found to be modified later than it was compiled (due to nondeterminism). That is, nondeterminism is what makes the test pass sometimes, not fail. If you eliminate nondeterminism (for example, by ensuring that there is a long enough sleep between writing Bean.groovy and loading the scripts for the first time), the test always fails.
        Hide
        blackdrag blackdrag added a comment -

        Alessio, after totally rewriting the tests to not to use the file system anymore, but something custom I found that you are right in more than one way. It was indeed the case that a precompiled dependency is not picked up. This is now basically fixed. I still have a problem to solve though...

        In he current setup if I have script1 depending on Bean and script2 depending on it as well, if I recompiled script1 and Bean, because Bean changed, then script2 will not be recompiled, because the entries are all up to date

        Show
        blackdrag blackdrag added a comment - Alessio, after totally rewriting the tests to not to use the file system anymore, but something custom I found that you are right in more than one way. It was indeed the case that a precompiled dependency is not picked up. This is now basically fixed. I still have a problem to solve though... In he current setup if I have script1 depending on Bean and script2 depending on it as well, if I recompiled script1 and Bean, because Bean changed, then script2 will not be recompiled, because the entries are all up to date
        Hide
        blackdrag blackdrag added a comment -

        the issue was marked as fixed for 2.0.2 and 1.8.8, but it seems due to the tests not always showing the real problem it was only partially fixed. This new version in 2.0.5 and 1.8.9 should finally fix the issue of not picking up dependencies. It is still no 100% satisfying solution to me, but at least it works

        Show
        blackdrag blackdrag added a comment - the issue was marked as fixed for 2.0.2 and 1.8.8, but it seems due to the tests not always showing the real problem it was only partially fixed. This new version in 2.0.5 and 1.8.9 should finally fix the issue of not picking up dependencies. It is still no 100% satisfying solution to me, but at least it works

          People

          • Assignee:
            blackdrag blackdrag
            Reporter:
            David Smith
          • Votes:
            4 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: