Try to keep a reference to the segmentStore if you're using that
backend. Eg, we do

// keep references to these
private Repository oakRepository = null;
private SegmentStore segmentStore = null;

// on webapp init

segmentStore = new FileStore(new File(oakRepositoryPath), 256);
NodeStore nodeStore = new SegmentNodeStore(segmentStore); // don't
keep the reference to the nodeStore
oakRepository = new Jcr(nodeStore).with(new LocalInitialContent())
  .withAsyncIndexing()
  .createRepository();

// on shutdown

if (oakRepository != null) {
  ((RepositoryImpl)oakRepository).shutdown();
  oakRepository = null;
}
if (segmentStore != null) {
  segmentStore.close();
}

There's still an unresolved bug that will give you exception on webapp
restart under tomcat, like

22-Jun-2015 16:59:51.228 WARNING [http-nio-8080-exec-143]
org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads
The web application [xx] appears to have started a thread named
[oak-scheduled-executor-37] but has failed to stop it. This is very
likely to create a memory leak. Stack trace of thread:

https://issues.apache.org/jira/browse/OAK-2736


On 22 June 2015 at 01:49, Frederic Gilbart <[email protected]> wrote:
> 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
>
>



-- 
-Tor

Reply via email to