I am using lucene to store an index of some data. The following code checks for the existance of a directory in /home/username and if its not found, builds the index from scratch creating the directories etc.
public static final String INDEX_PATH = "/home/username/appname/lucene/index";
private void buildCompleteIndex(int organizationId) {
synchronized(mutex) {
File path = new File(INDEX_PATH + "/" + String.valueOf(organizationId));
if(!path.exists()) {
try {
Utils.deleteDirectory(path);
} catch (IOException e) {
throw new LuceneIndexException("Error rebuilding index directory.", e);
}
path.mkdirs();
}
List<Contact> contactList = contactDAO.findAll(organizationId, true);
if(contactList != null) {
for(Contact contact : contactList) {
add(contact);
}
}
}
}
//Getters
private IndexReader getIndexReader(boolean readOnly, int organizationId) {
try {
if(directory == null) {
File path = getFile(organizationId);
directory = FSDirectory.open(path);
if(!IndexReader.indexExists(directory)) {
buildCompleteIndex(organizationId);
}
}
return IndexReader.open(directory, readOnly);
} catch (CorruptIndexException e) {
buildCompleteIndex(organizationId);
} catch (IOException e) {
buildCompleteIndex(organizationId);
}
return null;
}
This all works great in development when i'm deploying from a virtual tomcat instance inside of eclipse, but fails on the production server.
Why would I be able to write to the directory in dev mode, but not when the app is deployed on the server? Do I not have permission to create directories? I'm using Ubuntu Server 12.10 and Tomcat7.
How can I get this creating the proper folders and files on the server?
Is there a specific folder I am supposed to allow my applications to write to on the server? It always worked with the home/user folder on my dev box, but maybe thats different on the server because the user isn't actually logged in when the application is running?
UPDATE:
I checked the permissions of the folder which are currently set to 700. Could that be the problem? Is it safe to set this folder to 666 or 777 on a production server? Is this folder writable even if the username of /home/username is not logged in? I know that 700 means owner has full access, but does that include the tomcat application?
UPDATE: I attempted to change the /home/username's permissions to 755 and the same issue persisted.
The stacktrace showing the error generated when trying to create the folder.
java.io.IOException: Cannot create directory: /home/ryandlf/thinkbooked.com/lucene/contacts/1
at org.apache.lucene.store.NativeFSLock.obtain(NativeFSLockFactory.java:171)
at org.apache.lucene.store.Lock.obtain(Lock.java:72)
at org.apache.lucene.index.IndexWriter.<init>(IndexWriter.java:1108)
at com.thinkbooked.search.LuceneContactSearchEngine.getIndexWriter(LuceneContactSearchEngine.java:321)
at com.thinkbooked.search.LuceneContactSearchEngine.add(LuceneContactSearchEngine.java:68)
at com.thinkbooked.search.LuceneContactSearchEngine.buildCompleteIndex(LuceneContactSearchEngine.java:285)
at com.thinkbooked.search.LuceneContactSearchEngine.getIndexReader(LuceneContactSearchEngine.java:303)
at com.thinkbooked.search.LuceneContactSearchEngine.find(LuceneContactSearchEngine.java:150)
at com.thinkbooked.search.LuceneContactSearchEngine.find(LuceneContactSearchEngine.java:145)
at com.thinkbooked.handlers.ClientListSearchHandler.init(ClientListSearchHandler.java:49)
at com.thinkbooked.event.EventListener.doPost(EventListener.java:59)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Best Answer
The loop is almost certainly triggered by some Exception. I see a catch statement in
getIndexReader
that callsbuildCompleteIndex
, and the latter callsadd
and from the stack trace it's easy to infer thatadd
closes the loop. To get at the root of the issue you should understand the root cause.Which I can't possibly know. First try would be: replace all the code in the catch blocks with
printStackTrace()
and maybeSystem.exit()
to see if it yields more useful info about the firstException
that triggers everything else.