You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by "Hans-Peter Stoerr (Jira)" <ji...@apache.org> on 2021/05/31 07:39:00 UTC
[jira] [Comment Edited] (JCRVLT-525) FSPackageRegistry: XML
registry files can become corrupt
[ https://issues.apache.org/jira/browse/JCRVLT-525?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17354247#comment-17354247 ]
Hans-Peter Stoerr edited comment on JCRVLT-525 at 5/31/21, 7:38 AM:
--------------------------------------------------------------------
I've created a simple PR that solves the immediate problem, so that I can actually restart my server. I guess a write and move file solution would be more appropriate, but that'd require some testing and I currently don't have time to do something extensive here. It'd be nice if that could make it's way into the "official" snapshot, so we could use that for now.
BTW: a conceivable compromise that's easy to implement would be to save the XML into a ByteArrayOutputStream first, and then write that into the file. That'd remove most of the remaining risk of the remaining corruption risk, namely that an exception in save(OutputStream out) would leave a corrupted XML file in the registry. After all the XML files are very short, and an exception during writing it is quite unlikely. I could change the PR that way, if you want. That could look like:
{code}
public void save(Path file) throws IOException {
Files.createDirectories(file.getParent());
ByteArrayOutputStream buf = new ByteArrayOutputStream();
save(buf);
Files.copy(new ByteArrayInputStream(buf.toByteArray()), file, StandardCopyOption.REPLACE_EXISTING);
}
{code}
Thank you very much for your nice work on all these wonderful libraries!
was (Author: hanspeterstoerr):
I've created a simple PR that solves the immediate problem, so that I can actually restart my server. I guess a write and move file solution would be more appropriate, but that'd require some testing and I currently don't have time to do something extensive here. It'd be nice if that could make it's way into the "official" snapshot, so we could use that for now.
BTW: a conceivable compromise that's easy to implement would be to save the XML into a ByteArrayOutputStream first, and then write that into the file. That'd mostly remove the remaining risk that an exception in save(OutputStream out) would leave a corrupted XML file in the registry. After all the XML files are very short, and an exception during writing it is quite unlikely. I could change it that way, if you want.
Thank you very much for your nice work on all these wonderful libraries!
> FSPackageRegistry: XML registry files can become corrupt
> --------------------------------------------------------
>
> Key: JCRVLT-525
> URL: https://issues.apache.org/jira/browse/JCRVLT-525
> Project: Jackrabbit FileVault
> Issue Type: Bug
> Affects Versions: 3.5.0
> Environment: Sling-Starter 12-SNAPSHOT with JDK 11 on MacOS
> Reporter: Hans-Peter Stoerr
> Priority: Major
>
> When the FSPackageRegistry is updated, it can happen that the XML files become corrupt when they are updated. They are not truncated when they are rewritten, and if they become shorter, there are remnants of the old XML after the end of the newly written XML, so that there is a SAXParseException when they are read again (e.g. after restarting the server, see stacktrace below).
> The problem is pretty simple: in org.apache.jackrabbit.vault.packaging.registry.impl.FSInstallState#save(java.nio.file.Path) the file is opened with StandardOpenOption.CREATE, but it needs StandardOpenOption.TRUNCATE_EXISTING, like this:
> {code:java}
> try (OutputStream out = Files.newOutputStream(file, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
> {code}
> I'm worried a little that the best way to deal with those files would be to write the content to a temporary file, and replace the old one with the newly written one after that's been saved completely to disk. Otherwise they can become corrupted for other reasons, too, e.g. if the writing fails before it's completed.
> I stumbled over this when I'm using the Sling Feature Launcher and apply to [org.apache.sling.jcr.packageinit|https://github.com/apache/sling-org-apache-sling-jcr-packageinit] triggered by [org.apache.sling.extension.content|https://github.com/apache/sling-org-apache-sling-feature-extension-content] to deploy content packages from the feature launcher.
> By the way: the files become shorter that they originally contain a workspaceFilter section when they are initially written by org.apache.sling.jcr.packageinit , and that section disappears when the packages are updated when they are installed. That smells like a problem, but I'm not sure about that. I'll append a stacktrace of the point when they are written, too.
> Log messages during restart with the stacktrace where the reading fails:
> {code:java}
> [INFO][INFO] Apache Sling Application Launcher[INFO] ---------------------------------[INFO] Initializing...[INFO] Artifact Repositories: [jar:file:/Users/hps/dev/composum/composum-launch/feature/composumstarter/target/composum-launcher-feature-composumstarter-1.2.1-SNAPSHOT-oak_tar-launcher.jar!/lib][INFO] Assembling final feature model...[INFO][INFO] Assembling launcher...[Fatal Error] composum-platform-models-package-1.3.1-SNAPSHOT.xml:5:2: Content is not allowed in trailing section.[ERROR] Error while assembling launcher: Configuration file syntax error. java.io.IOException: Configuration file syntax error.
> at shaded.org.apache.jackrabbit.vault.packaging.registry.impl.FSInstallState.fromStream(FSInstallState.java:245)
> at shaded.org.apache.jackrabbit.vault.packaging.registry.impl.FSInstallState.fromFile(FSInstallState.java:173)
> at shaded.org.apache.jackrabbit.vault.packaging.registry.impl.FSPackageRegistry.loadPackageCache(FSPackageRegistry.java:604)
> at shaded.org.apache.jackrabbit.vault.packaging.registry.impl.FSPackageRegistry.<init>(FSPackageRegistry.java:127)
> at org.apache.sling.feature.extension.content.ContentHandler.buildExecutionPlan(ContentHandler.java:72)
> at org.apache.sling.feature.extension.content.ContentHandler.handle(ContentHandler.java:127)
> at org.apache.sling.feature.launcher.impl.FeatureProcessor.prepareLauncher(FeatureProcessor.java:212)
> at org.apache.sling.feature.launcher.impl.Bootstrap.run(Bootstrap.java:160)
> at org.apache.sling.feature.launcher.impl.Main.main(Main.java:200)
> at com.composum.platform.feature.nodesstarter.LaunchFromEmbeddedFAR.run(LaunchFromEmbeddedFAR.java:65)
> at com.composum.platform.feature.nodesstarter.LaunchFromEmbeddedFAR.main(LaunchFromEmbeddedFAR.java:55)
> Caused by: org.xml.sax.SAXParseException; systemId: file:///Users/hps/dev/composum/composum-launch/feature/composumstarter/target/launcher/repository/packageregistry/com/composum/platform/composum-platform-models-package-1.3.1-SNAPSHOT.xml; lineNumber: 5; columnNumber: 2; Content is not allowed in trailing section.
> at java.xml/com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:261)
> at java.xml/com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
> at java.xml/javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:151)
> at shaded.org.apache.jackrabbit.vault.packaging.registry.impl.FSInstallState.fromStream(FSInstallState.java:193)
> ... 10 more
> {code}
> Stacktrace where the files are written (and corrupted):
> {code:java}
> put:198, FSInstallStateCache (org.apache.jackrabbit.vault.packaging.registry.impl)
> updatePackageStatus:166, FSInstallStateCache (org.apache.jackrabbit.vault.packaging.registry.impl)
> installPackage:627, FSPackageRegistry (org.apache.jackrabbit.vault.packaging.registry.impl)
> doInstall:193, PackageTaskImpl (org.apache.jackrabbit.vault.packaging.registry.impl)
> execute:118, PackageTaskImpl (org.apache.jackrabbit.vault.packaging.registry.impl)
> execute:129, ExecutionPlanImpl (org.apache.jackrabbit.vault.packaging.registry.impl)
> execute:344, ExecutionPlanBuilderImpl (org.apache.jackrabbit.vault.packaging.registry.impl)
> processRepository:165, ExecutionPlanRepoInitializer (org.apache.sling.jcr.packageinit.impl)
> addingService:473, AbstractSlingRepositoryManager$2 (org.apache.sling.jcr.base)
> addingService:462, AbstractSlingRepositoryManager$2 (org.apache.sling.jcr.base)
> customizerAdding:943, ServiceTracker$Tracked (org.osgi.util.tracker)
> customizerAdding:871, ServiceTracker$Tracked (org.osgi.util.tracker)
> trackAdding:256, AbstractTracked (org.osgi.util.tracker)
> track:229, AbstractTracked (org.osgi.util.tracker)
> serviceChanged:903, ServiceTracker$Tracked (org.osgi.util.tracker)
> invokeServiceListenerCallback:990, EventDispatcher (org.apache.felix.framework)
> fireEventImmediately:838, EventDispatcher (org.apache.felix.framework)
> fireServiceEvent:545, EventDispatcher (org.apache.felix.framework)
> fireServiceEvent:4833, Felix (org.apache.felix.framework)
> registerService:3804, Felix (org.apache.felix.framework)
> registerService:328, BundleContextImpl (org.apache.felix.framework)
> register:929, AbstractComponentManager$3 (org.apache.felix.scr.impl.manager)
> register:915, AbstractComponentManager$3 (org.apache.felix.scr.impl.manager)
> changeRegistration:133, RegistrationManager (org.apache.felix.scr.impl.manager)
> registerService:984, AbstractComponentManager (org.apache.felix.scr.impl.manager)
> activateInternal:752, AbstractComponentManager (org.apache.felix.scr.impl.manager)
> enableInternal:674, AbstractComponentManager (org.apache.felix.scr.impl.manager)
> enable:437, AbstractComponentManager (org.apache.felix.scr.impl.manager)
> enableComponents:667, ConfigurableComponentHolder (org.apache.felix.scr.impl.manager)
> initialEnable:305, BundleComponentActivator (org.apache.felix.scr.impl)
> loadComponents:554, Activator (org.apache.felix.scr.impl)
> access$200:70, Activator (org.apache.felix.scr.impl)
> start:421, Activator$ScrExtension (org.apache.felix.scr.impl)
> createExtension:196, AbstractExtender (org.apache.felix.scr.impl)
> modifiedBundle:169, AbstractExtender (org.apache.felix.scr.impl)
> modifiedBundle:49, AbstractExtender (org.apache.felix.scr.impl)
> customizerModified:488, BundleTracker$Tracked (org.osgi.util.tracker)
> customizerModified:420, BundleTracker$Tracked (org.osgi.util.tracker)
> track:232, AbstractTracked (org.osgi.util.tracker)
> bundleChanged:450, BundleTracker$Tracked (org.osgi.util.tracker)
> invokeBundleListenerCallback:915, EventDispatcher (org.apache.felix.framework)
> fireEventImmediately:834, EventDispatcher (org.apache.felix.framework)
> fireBundleEvent:516, EventDispatcher (org.apache.felix.framework)
> fireBundleEvent:4817, Felix (org.apache.felix.framework)
> startBundle:2336, Felix (org.apache.felix.framework)
> setActiveStartLevel:1539, Felix (org.apache.felix.framework)
> run:308, FrameworkStartLevelImpl (org.apache.felix.framework)
> run:834, Thread (java.lang)
> {code}
--
This message was sent by Atlassian Jira
(v8.3.4#803005)