Java – Cannot Create Directory On Server. Permission Issue

iojava

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 calls buildCompleteIndex, and the latter calls add and from the stack trace it's easy to infer that add 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 maybe System.exit() to see if it yields more useful info about the first Exception that triggers everything else.