You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jackrabbit.apache.org by bgiles <bg...@coyotesong.com> on 2009/08/07 20:06:57 UTC

How to delete transient repository?

How do I delete a transient repository?  My code is successfully 
creating and shutting down the repository, but when I try to delete the 
directory (using jakarta commons IO) I get an exception because of some 
of the data files.  This happens even if I wait 15 seconds for 
multithreaded processes in the backend to finish.

Is there a standard way to do this that is guaranteed to work?  I don't 
want to clutter our CI system with hundreds of now-unused test 
repositories created by the automatic unit tests.

(I don't want to reuse the same transient repository because I want it 
in a known state.)

Thanks,

Bear

Re: How to delete transient repository?

Posted by Bear Giles <bg...@coyotesong.com>.
Those are actually input streams from ClassLoader resources, not files 
in the temporary repository, but I tried explicitly closing them just in 
case.  No joy.

Bear

Guo Du wrote:
> I didn't see you closed the inputstream in createRepository() , might
> be a problem?
>
> --Guo
>   

Re: How to delete transient repository?

Posted by Guo Du <mr...@gmail.com>.
I didn't see you closed the inputstream in createRepository() , might
be a problem?

--Guo

On Mon, Aug 10, 2009 at 6:22 PM, Bear Giles<bg...@coyotesong.com> wrote:
> I forgot about the in-memory FS, time to check the Wiki....
>
> My junit TestCase code follows.  The teardown method shuts down the
> repository, but I get an IOException (unable to delete a .bin file) even if
> I wait 15 seconds for unseen threads to terminate.
>
>
> /**
> * Test case for JCR tests.  This class handles creation of transient
> repository.
> */
> public abstract class AbstractJcrTestCase extends
> AbstractDependencyInjectionSpringContextTests {
>   private static final Logger logger =
> Logger.getLogger(AbstractJcrTestCase.class);
>   private static final String WORKSPACE_NAME = null;
>   protected Repository repository;
>   protected Credentials credentials = new SimpleCredentials("userid",
> "".toCharArray());
>   private String configFile =
> "gov/usda/aphis/vsps/dao/jcr/fileRepository.xml";
>   private String cndFile = "gov/usda/aphis/vsps/dao/jcr/vsps.cnd";
>   private File repositoryDirectory;
>
>   /**
>    * TODO: Document method
>    *
>    * @throws IOException TODO: Document exception
>    * @throws RuntimeRepositoryException TODO: Document exception
>    */
>   public void createRepository() throws IOException {
>       // read configuration stream
>       InputStream is = Thread.currentThread().getContextClassLoader()
>                              .getResourceAsStream(configFile);
>
>       if (is == null) {
>           throw new IOException("unable to open configuration stream!");
>       }
>
>       // identify good repository directory.
>       String tmpdir = System.getProperty("java.io.tmpdir");
>       repositoryDirectory = new File(new File(tmpdir),
>               "transient-jcr-repository-" + new Date().getTime());
>
>       if (logger.isInfoEnabled()) {
>           logger.info("repository location: " +
> repositoryDirectory.getAbsolutePath());
>       }
>
>       if (!repositoryDirectory.exists()) {
>           repositoryDirectory.mkdir();
>       }
>
>       // create repository.
>       RepositoryConfig config = null;
>
>       try {
>           config = RepositoryConfig.create(is,
> repositoryDirectory.getAbsolutePath());
>       } catch (RepositoryException e) {
>           throw new RuntimeRepositoryException(e);
>       }
>
>       repository = new TransientRepository(config);
>
>       // set up VSPS node types.
>       Session session = null;
>
>       try {
>           session = repository.login(credentials, WORKSPACE_NAME);
>
>           JackrabbitNodeTypeManager manager = (JackrabbitNodeTypeManager)
> session.getWorkspace()
>
>      .getNodeTypeManager();
>           is =
> Thread.currentThread().getContextClassLoader().getResourceAsStream(cndFile);
>           manager.registerNodeTypes(is,
> JackrabbitNodeTypeManager.TEXT_X_JCR_CND);
>       } catch (RepositoryException e) {
>           throw new RuntimeRepositoryException(e);
>       } finally {
>           if (session != null) {
>               session.logout();
>           }
>       }
>   }
>
>   /**
>    * Create repository on setup.
>    */
>   @Override
>   public void onSetUp() throws Exception {
>       super.onSetUp();
>       createRepository();
>   }
>
>   /**
>    * Destroy repository on teardown.
>    */
>   @Override
>   public void onTearDown() throws Exception {
>       // this should not be necessary with transient repository, but it
>       // won't hurt.
>       if (repository instanceof JackrabbitRepository) {
>           ((JackrabbitRepository) repository).shutdown();
>       }
>
>       // delete transient repository
>       if ((repositoryDirectory != null) && repositoryDirectory.exists()) {
>           //FileUtils.deleteDirectory(repositoryDirectory);
>       }
>
>       super.onTearDown();
>   }
> }
>
>
> Thomas Müller wrote:
>>
>> Hi,
>>
>>
>>>
>>> How do I delete a transient repository?  My code is successfully creating
>>> and shutting down the repository, but when I try to delete the directory
>>> (using jakarta commons IO) I get an exception because of some of the data
>>> files.
>>>
>>
>> That sounds like a bug in Jackrabbit. Which files can not be deleted?
>>
>>
>>>
>>> Is there a standard way to do this that is guaranteed to work?
>>>
>>
>> Use Linux. Just joking.
>>
>> Did you consider using in-memory file system and persistence managers?
>>
>> Regards,
>> Thomas
>>
>
>

Re: How to delete transient repository?

Posted by Bear Giles <bg...@coyotesong.com>.
I forgot about the in-memory FS, time to check the Wiki....

My junit TestCase code follows.  The teardown method shuts down the 
repository, but I get an IOException (unable to delete a .bin file) even 
if I wait 15 seconds for unseen threads to terminate.


/**
 * Test case for JCR tests.  This class handles creation of transient 
repository.
 */
public abstract class AbstractJcrTestCase extends 
AbstractDependencyInjectionSpringContextTests {
    private static final Logger logger = 
Logger.getLogger(AbstractJcrTestCase.class);
    private static final String WORKSPACE_NAME = null;
    protected Repository repository;
    protected Credentials credentials = new SimpleCredentials("userid", 
"".toCharArray());
    private String configFile = 
"gov/usda/aphis/vsps/dao/jcr/fileRepository.xml";
    private String cndFile = "gov/usda/aphis/vsps/dao/jcr/vsps.cnd";
    private File repositoryDirectory;

    /**
     * TODO: Document method
     *
     * @throws IOException TODO: Document exception
     * @throws RuntimeRepositoryException TODO: Document exception
     */
    public void createRepository() throws IOException {
        // read configuration stream
        InputStream is = Thread.currentThread().getContextClassLoader()
                               .getResourceAsStream(configFile);

        if (is == null) {
            throw new IOException("unable to open configuration stream!");
        }

        // identify good repository directory.
        String tmpdir = System.getProperty("java.io.tmpdir");
        repositoryDirectory = new File(new File(tmpdir),
                "transient-jcr-repository-" + new Date().getTime());

        if (logger.isInfoEnabled()) {
            logger.info("repository location: " + 
repositoryDirectory.getAbsolutePath());
        }

        if (!repositoryDirectory.exists()) {
            repositoryDirectory.mkdir();
        }

        // create repository.
        RepositoryConfig config = null;

        try {
            config = RepositoryConfig.create(is, 
repositoryDirectory.getAbsolutePath());
        } catch (RepositoryException e) {
            throw new RuntimeRepositoryException(e);
        }

        repository = new TransientRepository(config);

        // set up VSPS node types.
        Session session = null;

        try {
            session = repository.login(credentials, WORKSPACE_NAME);

            JackrabbitNodeTypeManager manager = 
(JackrabbitNodeTypeManager) session.getWorkspace()
                                                                                   
.getNodeTypeManager();
            is = 
Thread.currentThread().getContextClassLoader().getResourceAsStream(cndFile);
            manager.registerNodeTypes(is, 
JackrabbitNodeTypeManager.TEXT_X_JCR_CND);
        } catch (RepositoryException e) {
            throw new RuntimeRepositoryException(e);
        } finally {
            if (session != null) {
                session.logout();
            }
        }
    }

    /**
     * Create repository on setup.
     */
    @Override
    public void onSetUp() throws Exception {
        super.onSetUp();
        createRepository();
    }

    /**
     * Destroy repository on teardown.
     */
    @Override
    public void onTearDown() throws Exception {
        // this should not be necessary with transient repository, but it
        // won't hurt.
        if (repository instanceof JackrabbitRepository) {
            ((JackrabbitRepository) repository).shutdown();
        }

        // delete transient repository
        if ((repositoryDirectory != null) && repositoryDirectory.exists()) {
            //FileUtils.deleteDirectory(repositoryDirectory);
        }

        super.onTearDown();
    }
}


Thomas Müller wrote:
> Hi,
>
>   
>> How do I delete a transient repository?  My code is successfully creating
>> and shutting down the repository, but when I try to delete the directory
>> (using jakarta commons IO) I get an exception because of some of the data
>> files.
>>     
>
> That sounds like a bug in Jackrabbit. Which files can not be deleted?
>
>   
>> Is there a standard way to do this that is guaranteed to work?
>>     
>
> Use Linux. Just joking.
>
> Did you consider using in-memory file system and persistence managers?
>
> Regards,
> Thomas
>   


Re: How to delete transient repository?

Posted by Bear Giles <bg...@coyotesong.com>.
Thomas Müller wrote
> Did you consider using in-memory file system and persistence managers?
>
> Regards,
> Thomas
>   
I must have forgotten my coffee this morning.  I created a config file 
using in-memory FS and PM, but RepositoryConfig still expects the path 
to the repository location and TransientRepository populates it with at 
least some data.  I missed any other obvious way to create a temporary 
repository.  None of the RepositoryFactory classes seem appropriate.

It did make one change though - the user-defined node types aren't 
getting set now.  I didn't see any error messages explaining why.

Bear

Re: How to delete transient repository?

Posted by Bear Giles <bg...@coyotesong.com>.
Hee.  It gets better.

I have two unit tests now.  One tests the DAO that wraps access to 
unversioned nt:resources, the second tests the DAO that wraps access to 
versioned nt:resources.

Either test, by itself, works.

Both run (via the eclipse junit test on a source folder) has the second 
one fails.  I don't know if it's due to the test itself or merely its 
position as second.  The error is on teardown - I can't delete the 
repository files.

However if I comment out a final method that simply reads the properties 
of the jcr:content associated with a specified node then both tests 
succeed.  I've single-stepped through the code and I'm not throwing any 
unexpected exceptions that would prevent the session from being properly 
closed.  Plus I -know- that the unit test succeeds when I run it by itself.

My only idea was that there's a race condition where the second unit 
test is trying to use a repository directory with the same name as the 
first unit test, but that doesn't hold up either since I get the problem 
even when I append a random number to the directory name.

Could there be other race conditions in transient repositories?

Bear

Re: How to delete transient repository?

Posted by Bear Giles <bg...@coyotesong.com>.
Thomas Müller wrote:
> Did you consider using in-memory file system and persistence managers?
>
> Regards,
> Thomas
>   

I finally remembered that TransientRepository resets after each 'last 
session' is closed and my unit test needs to keep a foot-in-the-door 
session open between setup and teardown.  With an in-memory FS and PM I 
can delete the transient repository directory on teardown.

BUT it looks like it's still writing to the FS.  Perhaps because I'm 
only creating extremely small content?  It's not critical as I can run 
the unit tests now, but would like to document the behavior if this is 
expected.

Configuration file:

    
<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD 
Jackrabbit 1.5//EN"
                          
"http://jackrabbit.apache.org/dtd/repository-1.5.dtd">

<Repository>
    <FileSystem class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>
    <Security appName="Jackrabbit">
        <SecurityManager
            
class="org.apache.jackrabbit.core.security.simple.SimpleSecurityManager"
            workspaceName="security" />
        <!--  WorkspaceAccessManager class=... -->
        <!--  <param name="config" value="${rep.home}/security.xml"/> -->
        <AccessManager
            class="org.apache.jackrabbit.core.security.SimpleAccessManager">
            <!--  <param name="config" value="${rep.home}/access.xml"/> -->
        </AccessManager>
        <LoginModule
            
class="org.apache.jackrabbit.core.security.simple.SimpleLoginModule">
            <param name="anonymousId" value="anonymous" />
            <param name="adminId" value="admin" />
        </LoginModule>
    </Security>

    <Workspaces rootPath="${rep.home}/workspaces"
        defaultWorkspace="default" />

    <Workspace name="${wsp.name}">
        <FileSystem 
class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>
        <PersistenceManager
            
class="org.apache.jackrabbit.core.persistence.mem.InMemPersistenceManager" 
/>
    </Workspace>

    <Versioning rootPath="${rep.home}/versions">
        <FileSystem 
class="org.apache.jackrabbit.core.fs.mem.MemoryFileSystem"/>
        <PersistenceManager
            
class="org.apache.jackrabbit.core.persistence.mem.InMemPersistenceManager" 
/>
    </Versioning>
</Repository>

Re: How to delete transient repository?

Posted by Thomas Müller <th...@day.com>.
Hi,

> How do I delete a transient repository?  My code is successfully creating
> and shutting down the repository, but when I try to delete the directory
> (using jakarta commons IO) I get an exception because of some of the data
> files.

That sounds like a bug in Jackrabbit. Which files can not be deleted?

> Is there a standard way to do this that is guaranteed to work?

Use Linux. Just joking.

Did you consider using in-memory file system and persistence managers?

Regards,
Thomas