1 Reply Latest reply on Jan 8, 2008 6:08 AM by Dimitris Andreadis

    VFS (URL) cache

    Ales Justin Master

      I was looking into how to cache some things with VirtualFileURLConnection.
      A simple initial attempt, to push things fwd:
      - http://anonsvn.jboss.org/repos/jbossas/projects/vfs/branches/cache-work/

      What I tried to do is register every created VirtualFileHandler into cache - the key is VirtualFileHandler's vfs URL:

       if (vfsUrl != null)
       CacheLocator.getUrlCache().put(vfsUrl, this);
      


      So when a VirtualFileURLConnection tries to access VirtualFile(Handler) we don't need to re-create the whole structure if it already exists.

       public static VirtualFileHandler resolveVirtualFileHandler(URL vfsurl, String relativePath) throws IOException
       {
       VFS vfs = VFS.getVFS(vfsurl);
       return vfs.findChild(relativePath).getHandler();
       }
      
       public synchronized VirtualFileHandler getVirtualFileHandler() throws IOException
       {
       if (handler == null)
       {
       boolean trace = log.isTraceEnabled();
       handler = CacheLocator.getUrlCache().get(vfsurl);
       if (handler == null)
       {
       handler = resolveVirtualFileHandler(vfsurl, relativePath);
       if (trace)
       log.trace("Resolving virtual file handler: " + vfsurl + "/" + relativePath);
       }
       else if (trace)
       log.trace("Handler resolved from cache: " + vfsurl + "/" + relativePath);
       }
       return handler;
       }
      
       public InputStream getInputStream() throws IOException
       {
       return getVirtualFileHandler().openStream();
       }
      


      Since a AbstractVFSDeployment holds a strong ref to VirtualFile root, the whole structure should be there already (once touched), hence it should be possible to implement a simple cache with weak refs.
      This didn't seam to be the case (or is it?), as weak refs were quickly gced - at least that's how it looked since no cache hits were present.
      So and attempt was made with soft refs. :-)

      This speeds up AS5 quite a bit, but I got a few failures. :-)
      2008-01-07 22:00:14,125 TRACE [org.jboss.virtual.plugins.vfs.VirtualFileURLConnection] Handler resolved from cache: vfsfile:/C:/projects/jboss5/trunk/build/output/jboss-5.0.0.Beta3/server/default/deploy/jboss-local-jdbc.rar/META-INF/ra.xml
      2008-01-07 22:00:14,140 DEBUG [org.jboss.resource.deployers.RARParserDeployer] Error during deploy: vfsfile:/C:/projects/jboss5/trunk/build/output/jboss-5.0.0.Beta3/server/default/deploy/jboss-local-jdbc.rar
      org.jboss.deployers.spi.DeploymentException: Error parsing meta data jboss-local-jdbc.rar/META-INF/ra.xml
       at org.jboss.deployers.spi.DeploymentException.rethrowAsDeploymentException(DeploymentException.java:49)
       at org.jboss.deployers.vfs.spi.deployer.ObjectModelFactoryDeployer.parse(ObjectModelFactoryDeployer.java:124)
       at org.jboss.deployers.vfs.spi.deployer.AbstractVFSParsingDeployer.parse(AbstractVFSParsingDeployer.java:86)
       at org.jboss.deployers.spi.deployer.helpers.AbstractParsingDeployerWithOutput.createMetaData(AbstractParsingDeployerWithOutput.java:223)
       at org.jboss.deployers.spi.deployer.helpers.AbstractParsingDeployerWithOutput.createMetaData(AbstractParsingDeployerWithOutput.java:199)
       at org.jboss.deployers.spi.deployer.helpers.AbstractParsingDeployerWithOutput.deploy(AbstractParsingDeployerWithOutput.java:162)
       at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:169)
       at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:853)
       at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:794)
       at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:327)
       at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1309)
       at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:734)
       at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:862)
       at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:784)
       at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:622)
       at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:411)
       at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:498)
       at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:506)
       at org.jboss.system.server.profileservice.ProfileServiceBootstrap.loadProfile(ProfileServiceBootstrap.java:245)
       at org.jboss.system.server.profileservice.ProfileServiceBootstrap.start(ProfileServiceBootstrap.java:131)
       at org.jboss.bootstrap.AbstractServerImpl.start(AbstractServerImpl.java:408)
       at org.jboss.Main.boot(Main.java:208)
       at org.jboss.Main$1.run(Main.java:534)
       at java.lang.Thread.run(Thread.java:595)
      Caused by: org.jboss.xb.binding.JBossXBException: Failed to parse source: vfsfile:/C:/projects/jboss5/trunk/build/output/jboss-5.0.0.Beta3/server/default/deploy/jboss-local-jdbc.rar/META-INF/ra.xml@1,1
       at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBParser.java:177)
       at org.jboss.xb.binding.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:186)
       at org.jboss.deployers.vfs.spi.deployer.ObjectModelFactoryDeployer.parse(ObjectModelFactoryDeployer.java:120)
       ... 22 more
      Caused by: org.xml.sax.SAXException: Content is not allowed in prolog. @ vfsfile:/C:/projects/jboss5/trunk/build/output/jboss-5.0.0.Beta3/server/default/deploy/jboss-local-jdbc.rar/META-INF/ra.xml[1,1]
       at org.jboss.xb.binding.parser.sax.SaxJBossXBParser$MetaDataErrorHandler.fatalError(SaxJBossXBParser.java:438)
       at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
       at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
       at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
       at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
       at org.apache.xerces.impl.XMLDocumentScannerImpl$PrologDispatcher.dispatch(Unknown Source)
       at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
       at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
       at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
       at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
       at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
       at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
       at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBParser.java:173)
       ... 24 more
      

      And I don't see what exactly causes this.
      The input stream for this should be from this piece of code - NoCopyNestedJarHandler:
       public InputStream openStream() throws IOException
       {
       return getJar().getInputStream(getEntry());
       }
      

      Which should be there, even if cached.

      Looking at the log, I do get a lot of cache hits, which somehow points to the right track.
      Any thoughts or other ideas on how to cache VFS?