1 2 Previous Next 20 Replies Latest reply on Aug 30, 2008 5:39 AM by mstruk

    JBoss with spaces in the directory name

      https://jira.jboss.org/jira/browse/JBAS-5796

      The initial problem is in the main class,
      which needs the file converting to a URI before creating the URL
      for jboss.home.url
      otherwise it doesn't encode the URL properly

      [ejort@warjort main]$ svn diff
      Index: src/main/org/jboss/Main.java
      ===================================================================
      --- src/main/org/jboss/Main.java (revision 76000)
      +++ src/main/org/jboss/Main.java (working copy)
      @@ -138,7 +138,7 @@
       if (homeURL == null)
       {
       File file = new File(homeDir);
      - homeURL = file.toURL().toString();
      + homeURL = file.toURI().toURL().toString();
       props.setProperty(ServerConfig.HOME_URL, homeURL);
       }
      


      The next problem is that the property editors aren't handling encoded
      URLs/URIs properly:

      https://jira.jboss.org/jira/browse/JBCOMMON-60

      After that there some problem in the VFS:
      Caused by: org.jboss.mx.util.JBossNotCompliantMBeanException: Error parsing the XML file, from XMLMetaData:
       at org.jboss.mx.metadata.XMLMetaData.build(XMLMetaData.java:292)
       at org.jboss.mx.modelmbean.XMBean.<init>(XMBean.java:253)
       at org.jboss.mx.modelmbean.XMBean.<init>(XMBean.java:282)
       at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
       at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
       at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
       at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
       at org.jboss.mx.server.MBeanServerImpl.instantiate(MBeanServerImpl.java:1242)
       at org.jboss.mx.server.MBeanServerImpl.instantiate(MBeanServerImpl.java:286)
       at org.jboss.mx.server.MBeanServerImpl.createMBean(MBeanServerImpl.java:344)
       at org.jboss.system.ServiceCreator.installExternalXMBean(ServiceCreator.java:286)
       at org.jboss.system.ServiceCreator.install(ServiceCreator.java:122)
       ... 38 more
      Caused by: org.dom4j.DocumentException: Child not found jboss-5.0.0.CR2%20test/server/default/conf/xmdesc/AttributePersistenceService-xmbean.xml for FileHandler@166961
      1[path= context=file:/home/ejort/jboss-head/build/output/ real=file:/home/ejort/jboss-head/build/output/] Nested exception: Child not found jboss-5.0.0.CR2%20test/serv
      er/default/conf/xmdesc/AttributePersistenceService-xmbean.xml for FileHandler@1669611[path= context=file:/home/ejort/jboss-head/build/output/ real=file:/home/ejort/jbo
      ss-head/build/output/]
       at org.dom4j.io.SAXReader.read(SAXReader.java:484)
       at org.dom4j.io.SAXReader.read(SAXReader.java:291)
       at org.jboss.mx.metadata.XMLMetaData.build(XMLMetaData.java:255)
       ... 49 more
      


      Probably because the FileHandler is looking for a directory called?
      boss-5.0.0.CR2%20test

      I'm fixing the first two problems. Ales, I'll let you look at the VFS issue. ;-)

        • 1. Re: JBoss with spaces in the directory name

           

          "adrian@jboss.org" wrote:

          I'm fixing the first two problems. Ales, I'll let you look at the VFS issue. ;-)


          I'd guess the fix invloves adding a
          URLDecoder.decode(uri, "UTF-8");
          to FileSystemContext.getFile(URI)
          but there might be other places that need this fix?

          • 2. Re: JBoss with spaces in the directory name
            alesj

             

            "adrian@jboss.org" wrote:

            I'd guess the fix invloves adding a
            URLDecoder.decode(uri, "UTF-8");
            to FileSystemContext.getFile(URI)
            but there might be other places that need this fix?

            Shouldn't the URI and File take care of those %20 'chars'?

            I'm trying to put together a test that would fail,
            but so far no luck. :-)

            I've added this
             public void testPathWithSpaces() throws Throwable
             {
             String path = "/test/pckg with spaces/somefile.txt";
             VirtualFile vf = testPath(path);
             assertNotNull(vf);
             URI uri = getResource("/vfs").toURI();
             String uriPath = uri.getPath();
             URI fileURI = vf.toURI();
             String fileURIPath = fileURI.getPath();
             assertEquals(uriPath + path, fileURIPath);
             }
            

            but all is ok. :-)

            Since your case fails when looking up child,
            perhaps a proper fix would be to fix the path
            in VirtualFile::getChild.

             public static String fixName(String name)
             {
             if (name == null)
             throw new IllegalArgumentException("Null name");
            
             int length = name.length();
             if (length <= 1)
             return name;
             if (name.charAt(length-1) == '/')
             return name.substring(0, length-1);
            
             return decode(name);
             }
            
             /**
             * Decode the path with UTF-8 encoding..
             *
             * @param path the path to decode
             * @return decoded path
             */
             public static String decode(String path)
             {
             return decode(path, DEFAULT_ENCODING);
             }
            


            • 3. Re: JBoss with spaces in the directory name

              No, we don't want to decode the path unless it is really necessary.
              getChild() is already slow enough in parsing the path, see PathTokenizer
              on a different thread.

              Anyway, I don't know exactly what is going on with the error above.
              Try booting jboss-head with the latest jboss-common-core
              and you'll see the error message, but dom4j is eating the stacktrace.

              If I had to guess, it would be something like the second part of this code,
              but this shows another bug (this code loops until it eventually consumes
              all heap memory!)

              I basically did:
              cd ~
              mkdir -p temp/spaces\ test
              touch temp/spaces\ test/file.txt

              import java.io.File;
              import java.net.URI;
              import java.net.URL;
              
              import org.jboss.virtual.VFS;
              import org.jboss.virtual.VirtualFile;
              
              public class Test
              {
               public static void main(String[] args) throws Exception
               {
               File temp = new File("/home/ejort/temp/");
               URI uri = temp.toURI();
               VirtualFile vf = VFS.getRoot(uri);
               System.out.println("vf=" + vf.getChild("spaces test/file.txt"));
              
               URL url = vf.toURL();
               URL file = new URL(url, "spaces%20test/file.txt");
               System.out.println("url=" + file);
               System.out.println("stream=" + file.openStream());
               }
              }
              




              • 4. Re: JBoss with spaces in the directory name

                 

                "adrian@jboss.org" wrote:
                No, we don't want to decode the path unless it is really necessary.
                getChild() is already slow enough in parsing the path, see PathTokenizer
                on a different thread.


                In principle the paths passed to getChild() should already be decoded.
                i.e. in the vfs url handlers.

                • 5. Re: JBoss with spaces in the directory name
                  alesj

                  I still think the path should be decoded asap in the whole execution stack.
                  Since there might be a few similar cache points to this one I found in FileHandler:

                   public VirtualFileHandler createChildHandler(String name) throws IOException
                   {
                   File parentFile = getFile();
                   File child = new File(parentFile, name);
                   VirtualFileHandler handler = childCache.get(name);
                   // if a child has already been created use that
                   // if the child has been modified on disk then create a new handler
                   if (handler != null && handler.hasBeenModified())
                   {
                   handler = null;
                   }
                   if (handler == null)
                   {
                   FileSystemContext context = getVFSContext();
                   handler = context.createVirtualFileHandler(this, child);
                   if (handler != null)
                   childCache.put(name, handler);
                   }
                   return handler;
                   }
                  

                  e.g. if the name once comes with %20 and the 2nd time w/o, then we'll have two entries for the same file.

                  • 6. Re: JBoss with spaces in the directory name

                    It should NOT come in with %20 unless it is from the URLHandler.
                    i.e. it is an encoded url.

                    Magically changing values on people just leads to all sorts of trouble.
                    e.g. the uppercase/lowercase problem on windows

                    A further example.
                    What if I do

                    mkdir temp/my%20dir

                    I then do
                    temp.getChild("my%20dir");

                    Oops! Not found because it looked for "my dir" !!!!

                    By the way, the correct URL for the above is
                    file:///.../temp/my%2520dir
                    which decodes to my%20dir :-)

                    • 7. Re: JBoss with spaces in the directory name

                       

                      "adrian@jboss.org" wrote:
                      It should NOT come in with %20 unless it is from the URLHandler.
                      i.e. it is an encoded url.


                      Or you are creating the name from a URI.


                      • 8. Re: JBoss with spaces in the directory name

                         

                        "adrian@jboss.org" wrote:
                        It should NOT come in with %20 unless it is from the URLHandler.
                        i.e. it is an encoded url.


                        In case it is not obvious, it is the URLHandler that should do the decoding
                        if it is necessary.

                        • 9. Re: JBoss with spaces in the directory name
                          mstruk

                          I think I fixed spaces handling in VFS.

                          FileSystemContext.getFile(URI) was already doing a proper decoding - since it uses File constructor that takes URI as parameter.

                          The only place to fix was really in AbstractVFSHandler . openConnection() where URL was converted to string without being properly decoded.

                          There are still some issues that seem to be outside VFS.

                          I'm testing spaces support with jboss trunk, and there's something going on here I can't quite get to the bottom of ...

                          When I run jboss in a directory with spaces it still crashes:

                          10:32:18,955 INFO [ServerImpl] Server Home Dir: C:\Users\Devel\svnroot\jboss-5\build\output\jboss 5.0.0.CR2\server\default
                          10:32:18,955 INFO [ServerImpl] Server Home URL: file:/C:/Users/Devel/svnroot/jboss-5/build/output/jboss%205.0.0.CR2/server/default/
                          10:32:18,955 INFO [ServerImpl] Server Data Dir: C:\Users\Devel\svnroot\jboss-5\build\output\jboss 5.0.0.CR2\server\default\data
                          10:32:18,955 INFO [ServerImpl] Server Temp Dir: C:\Users\Devel\svnroot\jboss-5\build\output\jboss 5.0.0.CR2\server\default\tmp
                          10:32:18,956 INFO [ServerImpl] Server Config URL: file:/C:/Users/Devel/svnroot/jboss-5/build/output/jboss%205.0.0.CR2/server/default/conf/
                          10:32:18,956 INFO [ServerImpl] Server Library URL: file:/C:/Users/Devel/svnroot/jboss-5/build/output/jboss%205.0.0.CR2/server/default/lib/
                          10:32:18,956 INFO [ServerImpl] Root Deployment Filename: jboss-service.xml
                          ...
                          ...
                          


                          Notice a space in the name: 'jboss 5.0.0.CR2'.

                          In URLs it gets properly escaped: 'jboss%205.0.0.CR2'

                          But as deployment starts getting serious some code somewhere does another round of escaping ...

                          10:28:27,397 ERROR [AbstractKernelController] Error installing to Configured: name=VFSBootstrapScanner state=Instantiated
                          java.lang.RuntimeException: Error configuring property: URIList for VFSBootstrapScanner
                           at org.jboss.kernel.plugins.dependency.ConfigureAction.dispatchSetProperty(ConfigureAction.java:114)
                           at org.jboss.kernel.plugins.dependency.ConfigureAction.setAttributes(ConfigureAction.java:87)
                           at org.jboss.kernel.plugins.dependency.ConfigureAction.installActionInternal(ConfigureAction.java:44)
                           at org.jboss.kernel.plugins.dependency.InstallsAwareAction.installAction(InstallsAwareAction.java:54)
                           at org.jboss.kernel.plugins.dependency.InstallsAwareAction.installAction(InstallsAwareAction.java:42)
                           at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62)
                           at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71)
                           at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
                           ...
                           ...
                           ...
                          Caused by: java.lang.IllegalArgumentException: Null root, rootURI: file:/C:/Users/Devel/svnroot/jboss-5/build/output/jboss%25205.0.0.CR2/server/default/conf/jboss-service.xml, file: C:\Users\Devel\svnroot\jboss-5\build\output\jboss%205.0.0.CR2\server\default\conf\jboss-service.xml
                           at org.jboss.virtual.plugins.context.file.FileSystemContext.<init>(FileSystemContext.java:198)
                           at org.jboss.virtual.plugins.context.file.FileSystemContext.<init>(FileSystemContext.java:170)
                           at org.jboss.virtual.plugins.context.file.FileSystemContextFactory.getVFS(FileSystemContextFactory.java:65)
                           at org.jboss.virtual.VFS.getVFS(VFS.java:89)
                           at org.jboss.system.server.profileservice.VFSScanner.getVFforURI(VFSScanner.java:582)
                           at org.jboss.system.server.profileservice.VFSScanner.addURI(VFSScanner.java:280)
                           at org.jboss.system.server.profileservice.VFSScanner.setURIList(VFSScanner.java:179)
                           ...
                           ...
                           ...
                          


                          'jboss%205.0.0.CR2' suddenly became 'jboss%25205.0.0.CR2', and I'm pretty sure it's not VFS code that does that.

                          I tried to find how and where URIList for VFSBootstrapScanner gets set. I tracked it down to PropertyDispatcherWrapper where for VFSBootstrapScannerImpl a property value for URIList is specified as '${jboss.server.home.url}conf/jboss-service.xml'. So it uses variable resolution but I had no success finding anything more specific about it.

                          It's the following code in PropertyDispatchWrapper . execute() method:
                           PropertyInfo propertyInfo = BeanInfoUtil.getPropertyInfo(beanInfo, target, name);
                           ValueMetaData valueMetaData = property.getValue();
                           Object value = valueMetaData.getValue(propertyInfo.getType(), cl);
                           validatePropertyValue(context, target, propertyInfo, value);
                           beanInfo.setProperty(target, name, value);
                          

                          It's call to valueMetaData.getValue() in the third line that expands the property value from '${jboss.server.home.url}conf/jboss-service.xml' to 'file:/C:/Users/Devel/svnroot/jboss-5/build/output/jboss%25205.0.0.CR2/server/default/conf/jboss-service.xml'.

                          Here I get lost :)

                          - marko


                          • 10. Re: JBoss with spaces in the directory name

                             

                            "mstruk" wrote:

                            It's call to valueMetaData.getValue() in the third line that expands the property value from '${jboss.server.home.url}conf/jboss-service.xml' to 'file:/C:/Users/Devel/svnroot/jboss-5/build/output/jboss%25205.0.0.CR2/server/default/conf/jboss-service.xml'.

                            Here I get lost :)


                            Read the first post, I already fixed it, but it is not in a released version of common-core.
                            https://jira.jboss.org/jira/browse/JBCOMMON-60

                            Can you try building this yourself and copying it to $JBOSS_HOME/lib
                            to validate all the fixes work.
                            http://anonsvn.jboss.org/repos/common/common-core/trunk/

                            • 11. Re: JBoss with spaces in the directory name
                              mstruk

                               

                              Read the first post, I already fixed it, but it is not in a released version of common-core.
                              https://jira.jboss.org/jira/browse/JBCOMMON-60


                              I totally missed this one :)


                              Can you try building this yourself and copying it to $JBOSS_HOME/lib
                              to validate all the fixes work.
                              http://anonsvn.jboss.org/repos/common/common-core/trunk/


                              I did that, and it works much better, but I'm seeing something else now:

                              19:45:30,399 WARN [HDScanner] Scan failed
                              java.net.URISyntaxException: Illegal character in path at index 61: file:/C:/Users/Devel/svnroot/jboss-5/build/output/jboss 5.0.0.CR2/server/default/deploy/jboss-local-jdbc.rar
                               at java.net.URI$Parser.fail(URI.java:2809)
                               at java.net.URI$Parser.checkChars(URI.java:2982)
                               at java.net.URI$Parser.parseHierarchical(URI.java:3066)
                               at java.net.URI$Parser.parse(URI.java:3014)
                               at java.net.URI.<init>(URI.java:578)
                               at java.net.URL.toURI(URL.java:918)
                               at org.jboss.system.server.profile.basic.MetaDataAwareProfile.hasBeenModified(MetaDataAwareProfile.java:74)
                               at org.jboss.system.server.profile.basic.ProfileImpl.getModifiedDeployments(ProfileImpl.java:317)
                               at org.jboss.system.server.profileservice.hotdeploy.HDScanner.scan(HDScanner.java:260)
                               at org.jboss.system.server.profileservice.hotdeploy.HDScanner.run(HDScanner.java:221)
                               at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
                               at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
                               at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
                               at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
                               at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
                               at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
                               at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
                               at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
                               at java.lang.Thread.run(Thread.java:619)
                              


                              • 12. Re: JBoss with spaces in the directory name

                                That's coming from this code:

                                 protected boolean hasBeenModified(VirtualFile root) throws Exception
                                 {
                                 // get file:/ schema
                                 URL url = VFSUtils.getCompatibleURL(root);
                                 File file = new File(url.toURI());
                                


                                So there's obviously an issue with the getCompatibleURL() method in VFSUtils
                                or looking at the method, some problem with vfsfile: url not being encoded?

                                • 13. Re: JBoss with spaces in the directory name

                                   

                                  "adrian@jboss.org" wrote:

                                   protected boolean hasBeenModified(VirtualFile root) throws Exception
                                   {
                                   // get file:/ schema
                                   URL url = VFSUtils.getCompatibleURL(root);
                                   File file = new File(url.toURI());
                                  



                                  It also looks stupid to me that it converts it first to a URL and then to URI.
                                  Couldn't this be more optimised with a getCompatibleURI(VirtualFile) method
                                  in VFSUtils?

                                  • 14. Re: JBoss with spaces in the directory name
                                    mstruk

                                    I was checking if spaces issue is fixed and it doesn't seem to be. So tracing it back to the source I'm seeing test failures in jboss-common-core:

                                    Running org.jboss.test.util.test.propertyeditor.PropertyEditorsUnitTestCase
                                    file:/C:/path%20with%20space/tst.xml != file:/path with space/tst.xml
                                    Tests run: 4, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.155 sec <<< FAILURE!
                                    


                                    The failing test is the one testing URL encoding/decoding:
                                    Transform(org.jboss.util.propertyeditor.URLEditor@7e5a9de6) of file:/path with space/tst.xml equals file:/C:/path with space/tst.xml, output=file:/C:/path%20with%20space/tst.xml
                                    


                                    As if JBCOMMON-60 has crept back ...

                                    - marko


                                    1 2 Previous Next