Jetty
  1. Jetty
  2. JETTY-1154

Config error setting reloadInterval from context file

    Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 6.1.21, 6.1.22
    • Fix Version/s: 6.1.27
    • Component/s: Security and SSL
    • Labels:
      None
    • Environment:
      Jetty 6.1.22, Ubuntu 9.04
    • Number of attachments :
      1

      Description

      Attempting to setup a context file with a HashUserRealm which is reloaded at some interval (as described at http://docs.codehaus.org/display/JETTY/Realms), I get the following exception on start

      2009-12-10 11:22:53.758::WARN: Config error at <Set name="reloadInterval">500</Set>
      2009-12-10 11:22:53.758::WARN: Config error at <Set name="userRealm">
      <New class="org.mortbay.jetty.security.HashUserRealm"><Set name="name">Funnelback Administration</Set><Set name="config"><SystemProperty name="funnelback.installdir"/>/conf/realm.properties</Set><Set name="reloadInterval">500</Set></New>
      </Set>
      2009-12-10 11:22:53.759::WARN: Config error at <Get name="securityHandler"><Set name="userRealm">
      <New class="org.mortbay.jetty.security.HashUserRealm"><Set name="name">Funnelback Administration</Set><Set name="config"><SystemProperty name="funnelback.installdir"/>/conf/realm.properties</Set><Set name="reloadInterval">500</Set></New>
      </Set></Get>
      2009-12-10 11:22:53.759::WARN: EXCEPTION
      java.lang.NoSuchMethodException: class org.mortbay.jetty.security.HashUserRealm.setReloadInterval(class java.lang.String)
      at org.mortbay.xml.XmlConfiguration.set(XmlConfiguration.java:424)
      at org.mortbay.xml.XmlConfiguration.configure(XmlConfiguration.java:248)
      at org.mortbay.xml.XmlConfiguration.newObj(XmlConfiguration.java:626)
      at org.mortbay.xml.XmlConfiguration.itemValue(XmlConfiguration.java:915)
      at org.mortbay.xml.XmlConfiguration.value(XmlConfiguration.java:837)
      at org.mortbay.xml.XmlConfiguration.set(XmlConfiguration.java:286)
      at org.mortbay.xml.XmlConfiguration.configure(XmlConfiguration.java:248)
      at org.mortbay.xml.XmlConfiguration.get(XmlConfiguration.java:468)
      at org.mortbay.xml.XmlConfiguration.configure(XmlConfiguration.java:254)
      at org.mortbay.xml.XmlConfiguration.configure(XmlConfiguration.java:214)
      at org.mortbay.jetty.deployer.ContextDeployer.createContext(ContextDeployer.java:369)
      at org.mortbay.jetty.deployer.ContextDeployer.deploy(ContextDeployer.java:263)
      at org.mortbay.jetty.deployer.ContextDeployer.access$000(ContextDeployer.java:67)
      at org.mortbay.jetty.deployer.ContextDeployer$ScannerListener.fileAdded(ContextDeployer.java:89)
      at org.mortbay.util.Scanner.reportAddition(Scanner.java:410)
      at org.mortbay.util.Scanner.reportDifferences(Scanner.java:324)
      at org.mortbay.util.Scanner.scan(Scanner.java:280)
      at org.mortbay.jetty.deployer.ContextDeployer.doStart(ContextDeployer.java:327)
      at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
      at org.mortbay.jetty.Server.doStart(Server.java:201)
      at org.mortbay.setuid.SetUIDServer.doStart(SetUIDServer.java:158)
      at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
      at org.mortbay.xml.XmlConfiguration.main(XmlConfiguration.java:985)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.mortbay.start.Main.invokeMain(Main.java:194)
      at org.mortbay.start.Main.start(Main.java:534)
      at org.mortbay.start.Main.start(Main.java:441)
      at org.mortbay.start.Main.main(Main.java:119)

      My context file looks like...

      <?xml version="1.0" encoding="ISO-8859-1"?>
      <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://j
      etty.mortbay.org/configure.dtd">

      <Configure class="org.mortbay.jetty.webapp.WebAppContext">

      <Set name="contextPath">/search/admin/analytics</Set>
      <Set name="war"><SystemProperty name="installdir" />/web/webapps/analytics.war</Set>

      <Set name="extractWAR">false</Set>
      <Set name="copyWebDir">false</Set>

      <Get name="securityHandler">
      <Set name="userRealm">
      <New class="org.mortbay.jetty.security.HashUserRealm">
      <Set name="name">Funnelback Administration</Set>
      <Set name="config"><SystemProperty name="installdir" />/conf/realm.properties</Set>
      <Set name="reloadInterval">500</Set>
      <Call name="start"></Call>
      </New>
      </Set>
      </Get>

      </Configure>

      But from the exception I get, it seems that XmlConfiguration is expecting a setReloadInterval method which takes a string rather than the one which exists which takes an int.

      Is there any workaround for this or am I doing something obviously wrong? Perhaps my easiest way forward is to modify HashUserRealm to include a setReloadInterval(String) method which parses the string and passes it on.

        Activity

        Hide
        Jan Bartel added a comment -

        Michael,

        Can you investigate? I don't think this is a bug, probably a case of correctly specifying the type of the argument to the <reloadInterval> element.

        cheers
        Jan

        Show
        Jan Bartel added a comment - Michael, Can you investigate? I don't think this is a bug, probably a case of correctly specifying the type of the argument to the <reloadInterval> element. cheers Jan
        Hide
        Joakim Erdfelt added a comment -

        The field/variable isn't 'reloadInterval' its 'refreshInterval'

        Show
        Joakim Erdfelt added a comment - The field/variable isn't 'reloadInterval' its 'refreshInterval'
        Hide
        Joakim Erdfelt added a comment -
        Show
        Joakim Erdfelt added a comment - Fixed documentation typo at http://docs.codehaus.org/display/JETTY/Realms
        Hide
        Matt Sheppard added a comment -

        Thanks - I'll test that out.

        Show
        Matt Sheppard added a comment - Thanks - I'll test that out.
        Hide
        Matt Sheppard added a comment -

        Making that change does seem to have stopped the error, but unfortunately, the refreshing does not seem to occur - The realm.properties file can be edited, but the changes do not seem to take effect until after the server is restarted.

        For reference, I'm now using Jetty 6.1.24 with the following context file

        <?xml version="1.0"  encoding="ISO-8859-1"?>
        <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
        
        <Configure class="org.mortbay.jetty.webapp.WebAppContext">
        
          <Set name="contextPath">/search/admin/analytics</Set>
          <Set name="war"><SystemProperty name="installdir" />/web/webapps/analytics.war</Set>
        
          <Set name="extractWAR">true</Set>
          <Set name="copyWebDir">false</Set>
        
          <Get name="securityHandler">
            <Set name="userRealm">
              <New class="org.mortbay.jetty.security.HashUserRealm">
                <Set name="name">Administration</Set>
                <Set name="config"><SystemProperty name="installdir" />/conf/realm.properties</Set>
                <Set name="refreshInterval">5</Set>
                <Call name="start"></Call>
              </New>
            </Set>
          </Get>
        
        </Configure>
        

        and the following in realm.properties

        admin: CRYPT:ybbaVLhsGJPn6,report_viewer
        bob: CRYPT:olY1Z3k6efEGQ,report_viewer
        adam: CRYPT:A8f2PXda8DYD2,report_viewer
        dob: CRYPT:nUNGWS8GdcJZE,report_viewer
        
        Show
        Matt Sheppard added a comment - Making that change does seem to have stopped the error, but unfortunately, the refreshing does not seem to occur - The realm.properties file can be edited, but the changes do not seem to take effect until after the server is restarted. For reference, I'm now using Jetty 6.1.24 with the following context file <?xml version= "1.0" encoding= "ISO-8859-1" ?> <!DOCTYPE Configure PUBLIC "- //Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd" > <Configure class= "org.mortbay.jetty.webapp.WebAppContext" > <Set name= "contextPath" >/search/admin/analytics</Set> <Set name= "war" ><SystemProperty name= "installdir" />/web/webapps/analytics.war</Set> <Set name= "extractWAR" > true </Set> <Set name= "copyWebDir" > false </Set> <Get name= "securityHandler" > <Set name= "userRealm" > <New class= "org.mortbay.jetty.security.HashUserRealm" > <Set name= "name" >Administration</Set> <Set name= "config" ><SystemProperty name= "installdir" />/conf/realm.properties</Set> <Set name= "refreshInterval" >5</Set> <Call name= "start" ></Call> </New> </Set> </Get> </Configure> and the following in realm.properties admin: CRYPT:ybbaVLhsGJPn6,report_viewer bob: CRYPT:olY1Z3k6efEGQ,report_viewer adam: CRYPT:A8f2PXda8DYD2,report_viewer dob: CRYPT:nUNGWS8GdcJZE,report_viewer
        Hide
        Jan Bartel added a comment -

        Matt,

        I checked this with the standard jetty distro and uncommenting the HashUserRealm setup from contexts/test.xml and it is working. Can you try the same thing? My steps:

        1. edit etc/realm.properties and change the admin password (just because I forgot what it was to begin with!)
        2. start jetty
        3. surf to http://localhost:8080/dump/auth/admin
        4. enter admin as the username and whatever the password is you set in realm.properties
        5. you should see a dump of the request if you're logged in ok
        6. go to http://localhost:8080/sessions and invalidate the session
        7. edit etc/realm.properties and change the password.
        8. wait for the refresh interval
        9. surf to the url from #3 again and supply the new password at the form
        10. you should again be logged in

        If you repeat the above and it doesn't work for you let us know. Also, if you're doing something other than the above, also post and let us know your sequence of steps.

        cheers
        Jan

        Show
        Jan Bartel added a comment - Matt, I checked this with the standard jetty distro and uncommenting the HashUserRealm setup from contexts/test.xml and it is working. Can you try the same thing? My steps: edit etc/realm.properties and change the admin password (just because I forgot what it was to begin with!) start jetty surf to http://localhost:8080/dump/auth/admin enter admin as the username and whatever the password is you set in realm.properties you should see a dump of the request if you're logged in ok go to http://localhost:8080/sessions and invalidate the session edit etc/realm.properties and change the password. wait for the refresh interval surf to the url from #3 again and supply the new password at the form you should again be logged in If you repeat the above and it doesn't work for you let us know. Also, if you're doing something other than the above, also post and let us know your sequence of steps. cheers Jan
        Hide
        Matt Sheppard added a comment -

        Thanks Jan - That did seem to work within the test webapp, but was still failing in my setup.

        After quite a bit of digging, I think I've tracked down the problem - It looks to me like the refresh fails silently if the path given for the realm.properties file contains a symlink.

        For example, I changed the context test.xml to have to following...

        <Set name="config">/home/msheppard/Downloads/test/etc/realm.properties</Set>

        Within the HashUserRealm, where the 'test' directory is a symlink to my download of jetty-6.1.24 in the same directory. Following your steps after that, I see the same behaviour I saw in my setup (which did have a symlink in the path) - i.e. realm.properties never seems to be refreshed.

        Easy enough to work around now that I know that, but it may be worth fixing if possible or documenting (unless I missed it somewhere).

        Thanks for your help,
        Matt

        Show
        Matt Sheppard added a comment - Thanks Jan - That did seem to work within the test webapp, but was still failing in my setup. After quite a bit of digging, I think I've tracked down the problem - It looks to me like the refresh fails silently if the path given for the realm.properties file contains a symlink. For example, I changed the context test.xml to have to following... <Set name="config">/home/msheppard/Downloads/test/etc/realm.properties</Set> Within the HashUserRealm, where the 'test' directory is a symlink to my download of jetty-6.1.24 in the same directory. Following your steps after that, I see the same behaviour I saw in my setup (which did have a symlink in the path) - i.e. realm.properties never seems to be refreshed. Easy enough to work around now that I know that, but it may be worth fixing if possible or documenting (unless I missed it somewhere). Thanks for your help, Matt
        Hide
        Matt Sheppard added a comment - - edited

        Looks like it also has trouble with paths like...

        /tmp/dir1/../dir2/realm.properties (i.e. any containing ../)

        Show
        Matt Sheppard added a comment - - edited Looks like it also has trouble with paths like... /tmp/dir1/../dir2/realm.properties (i.e. any containing ../)
        Hide
        Nicolas Guillaumin added a comment - - edited

        Unfortunately it seems to be still partially broken on Windows: I can't get Jetty to refresh my realm file when using unix-style file separators like: C:/dev/realm.properties.

        This works well to access the file as Java converts to a Windows path, but the change detection mechanism seems broken using this file separator. Using C:\\dev
        realm.properties works fine.

        Show
        Nicolas Guillaumin added a comment - - edited Unfortunately it seems to be still partially broken on Windows: I can't get Jetty to refresh my realm file when using unix-style file separators like: C:/dev/realm.properties. This works well to access the file as Java converts to a Windows path, but the change detection mechanism seems broken using this file separator. Using C:\\dev realm.properties works fine.
        Hide
        P Sturge added a comment -

        Hello,

        For those interested in auto-reloading of realm,proeprties, I have found and fixed this issue.

        Basically, the problem (on Windows) is that the compare method in HashUserRealm.java wasn't taking into account relative paths and Windows wonderful Long name vs Short name conventions. Straightup string compares on Windows file paths never work consistently, because you can get back all sorts of different path formats from Windows.

        Sooooo..fortunately, the fix is quite simple, and, although I've not tested this on LUNIX, it should be just fine, as they are much more consistent with path handling.

        The code fix is in org.mortbay.jetty.security.HashUserRealm, line 413:

        • if (filenames.size()==1 && filenames.get(0).equals(_config))
          + if (filenames.size()==1 && new File(filenames.get(0).toString()).getCanonicalPath().equals(new File(_config).getCanonicalPath()))

        Using the canonical path name tells Windows to give a consistent path back (the Long form), which can be compared correctly.

        I've attached the source and class files to this comment (I hope that works).

        Hope this helps those of you who have been pulling your hair out trying to get this working!

        Cheers,
        midiman

        Show
        P Sturge added a comment - Hello, For those interested in auto-reloading of realm,proeprties, I have found and fixed this issue. Basically, the problem (on Windows) is that the compare method in HashUserRealm.java wasn't taking into account relative paths and Windows wonderful Long name vs Short name conventions. Straightup string compares on Windows file paths never work consistently, because you can get back all sorts of different path formats from Windows. Sooooo..fortunately, the fix is quite simple, and, although I've not tested this on LUNIX, it should be just fine, as they are much more consistent with path handling. The code fix is in org.mortbay.jetty.security.HashUserRealm, line 413: if (filenames.size()==1 && filenames.get(0).equals(_config)) + if (filenames.size()==1 && new File(filenames.get(0).toString()).getCanonicalPath().equals(new File(_config).getCanonicalPath())) Using the canonical path name tells Windows to give a consistent path back (the Long form), which can be compared correctly. I've attached the source and class files to this comment (I hope that works). Hope this helps those of you who have been pulling your hair out trying to get this working! Cheers, midiman
        Hide
        Michael Gorovoy added a comment -

        Modified code to use Java's built-in path comparison instead of attempting to compare paths manually.

        Show
        Michael Gorovoy added a comment - Modified code to use Java's built-in path comparison instead of attempting to compare paths manually.

          People

          • Assignee:
            Michael Gorovoy
            Reporter:
            Matt Sheppard
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: