Hi John,
I made the following class for running garbage collection in the datastore. I
don't need a transient repository with extra login for this. I only use the
actual RepositoryManagers(s).
Bye,
Ulrich
*************************************************************
import java.util.List;
import javax.jcr.RepositoryException;
import org.apache.jackrabbit.api.management.DataStoreGarbageCollector;
import org.apache.jackrabbit.api.management.RepositoryManager;
import edu.umd.cs.findbugs.annotations.SuppressWarnings;
/**
* The data store never deletes entries except when running data store garbage
* collection. Similar to Java heap garbage collection, data store garbage
* collection will first mark all used entries, and later remove unused items.
* <p>
* Data store garbage collection does not delete entries if the identifier is
* still in the Java heap memory. To delete as many unreferenced entries as
* possible, call System.gc() a few times before running the data store garbage
* collection. Please note System.gc() does not guarantee all objects are
* garbage collected.
*
* @author cech
*
*/
public class DataStoreGC extends Thread {
/**
* The logger for this class.
*/
private static org.apache.log4j.Logger logger =
org.apache.log4j.Logger.getLogger(DataStoreGC.class);
private List<RepositoryManager> repositoryManagers;
/**
* Constructs a new <code>DataStoreGC</code> with a list of
* <code>RepositoryManager</code> for which the garbage collection
* should run.
*/
public DataStoreGC(List<RepositoryManager> rms) {
super();
if (rms == null || rms.size() < 1) {
throw new IllegalArgumentException(
"The list of repository managers is empty.");
}
setRepositoryManagers(rms);
}
/**
* {@inheritDoc}
*/
@Override
public void run() {
while (Thread.currentThread().isInterrupted()) {
try {
System.out.println("Running DataStoreGC...");
runDataStoreGarbageCollector();
System.out.println("DataStoreGC done.");
Thread.sleep(10000);
} catch (InterruptedException irex) {
// ignore here
} catch (RepositoryException repoex) {
logger.error("Error while communicating with the repository.",
repoex);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {}
}
}
}
/**
* Runs the garbage collector for the given RepositoryManagers. If multiple
* repositories use the same data store, give all RepositoryManagers in the
* parameter list.
*
* @param rms
* @throws RepositoryException
*/
@SuppressWarnings(value="DM_GC")
private int runDataStoreGarbageCollector()
throws RepositoryException {
int result = 0;
List<RepositoryManager> rms = getRepositoryManagers();
if (rms == null || rms.size() < 1) {
throw new IllegalArgumentException(
"The list of repository managers is empty.");
}
DataStoreGarbageCollector[] gcs =
new DataStoreGarbageCollector[rms.size()];
for (int i = 0; i < 5; i++) {
System.gc(); //ignore FindBugs warning here
}
for (int i = 0; i < rms.size(); ++i) {
gcs[i] = rms.get(i).createDataStoreGarbageCollector();
}
try {
/* Mark all records in all repositories */
for (DataStoreGarbageCollector gc : gcs) {
gc.mark();
}
/* Important to call sweep() on the first GarbageCollector */
result = gcs[0].sweep();
} finally {
for (DataStoreGarbageCollector gc : gcs) {
gc.close();
}
}
return result;
}
private List<RepositoryManager> getRepositoryManagers() {
return repositoryManagers;
}
private void setRepositoryManagers(List<RepositoryManager>
repositoryManagers) {
this.repositoryManagers = repositoryManagers;
}
}
*************************************************************