VFS (URL) cache
alesj Jan 7, 2008 6:54 PMI 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?