Hi all,
I try to close all Oak resources when my webapp stops using a @PreDestroy.
I either use a DocumentNodeStore or a SegmentNodeStore for the application, and
I keep a reference using NodeStore.
For DocumentNodeStore I believe the .dispose() is right.
On the opposite SegmentNodeStore does not offer such a dispose() (nor a
.getBlobStore() as the DocumentNodeStore does which seems handy).
So I also keep another reference on the underlying BlobStore which requires a
cast to implementation to be closed : DataStore interface offers the .close()
but BlobStore doesn't, so I can't close any AbstractBlobStore, FileBlobStore;
etc...
When I stop webapp using Tomcat8 manager (Stop/Start), then start it I find
following log :
Caused by: java.io.IOException: Could not remove broken tar file C:
\DEV\repository\oak\data00021a.tar
at
org.apache.jackrabbit.oak.plugins.segment.file.TarReader.backupSafely(TarReader.java:179)
~[oak-core-1.2.2.jar:1.2.2]
at
org.apache.jackrabbit.oak.plugins.segment.file.TarReader.open(TarReader.java:132)
~[oak-core-1.2.2.jar:1.2.2]
at
org.apache.jackrabbit.oak.plugins.segment.file.FileStore.<init>(FileStore.java:359)
~[oak-core-1.2.2.jar:1.2.2]
at
org.apache.jackrabbit.oak.plugins.segment.file.FileStore.<init>(FileStore.java:82)
~[oak-core-1.2.2.jar:1.2.2]
at
org.apache.jackrabbit.oak.plugins.segment.file.FileStore$Builder.create(FileStore.java:292)
~[oak-core-1.2.2.jar:1.2.2]
at
fr.capsiel.startup.config.OakConfiguration.getRepository(OakConfiguration.java:60)
~[aladin-oak-3.0.0-SNAPSHOT.jar:na
]
at
fr.capsiel.startup.config.OakConfiguration$$EnhancerBySpringCGLIB$$ca54aa3d.CGLIB$getRepository$0(<generated>)
~[spri
ng-core-4.0.9.RELEASE.jar:na]
at
fr.capsiel.startup.config.OakConfiguration$$EnhancerBySpringCGLIB$$ca54aa3d$$FastClassBySpringCGLIB$$e557a109.invoke(
<generated>) ~[spring-core-4.0.9.RELEASE.jar:na]
at
org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
~[spring-core-4.0.9.RELEASE.jar:4.0.9.RELEASE]
at
org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer
.java:311) ~[spring-context-4.0.9.RELEASE.jar:4.0.9.RELEASE]
at
fr.capsiel.aladin.startup.config.OakConfiguration$$EnhancerBySpringCGLIB$$ca54aa3d.getRepository(<generated>)
~[spring-core-
4.0.9.RELEASE.jar:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
~[na:1.8.0_25]
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
~[na:1.8.0_25]
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
~[na:1.8.0_25]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]
at
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
~[sp
The webapp will never start due to mandatory @Autowired Repository bean.
Note : A full JVM restart (catalina restart) is fine: tar is managed, file
seems not lost, and webapp starts.
I could once again use another reference on SegmentStore wich offers .close()
or DocumentStore gives .dispose(), but no common interface exists. I could keep
2 references for sure.
Question is: am I wrong when I want to use either a Segment or a Document Node
Storage regarding local or distributed live target? Or am I using wrong API
level to manage both Storages, at least for shutdown?
Subsidiary question: what is recommended solution to gracefully close & release
Oak's resources on shutdown?
((RepositoryImpl)this.repository).shutdown(); does not help.
>From compiler's point of view:
@PreDestroy
void detroyTest() {
// No common interface between SegmentStore & DocumentStore
Object o = null;
if (o instanceof SegmentStore) {
((SegmentStore) o).close();
} else if (o instanceof DocumentStore) {
((DocumentStore) o).dispose();
}
NodeStore nodeStore = null;
if (nodeStore instanceof DocumentNodeStore) {
((DocumentNodeStore) nodeStore).dispose(); // ok
((DocumentNodeStore)
nodeStore).getDocumentStore();//useful, but lack corresponding getSegmentStore
((DocumentNodeStore)
this.nodeStore).getBlobStore().close(); // No close on NodeStore, could avoid
me to keep ref on it
} else if (nodeStore instanceof SegmentNodeStore) {
((SegmentNodeStore) nodeStore).getSegmentStore(); // no
.getSegmentStore()
((SegmentNodeStore) nodeStore).getBlobStore(); // no
.getBlobStore()
}
BlobStore blobStore = null;
if (blobStore instanceof DataStore) {
((DataStore) o).close();
} else if (blobStore instanceof DataStoreBlobStore) {
((DataStoreBlobStore) o).close();
} else if (blobStore instanceof FileBlobStore) {
((FileBlobStore) o).close();// no method
}
}
Regards,
Fred