What Determines the Current Working Directory of Tomcat Java Process

What determines the current working directory of Tomcat Java process?

On CentOS 6, the Tomcat init.d script launches tomcat by means of this line:

$SU - $TOMCAT_USER -c "${TOMCAT_SCRIPT} start-security"

$SU is either /bin/runuser or /bin/su, $TOMCAT_USER is normally "tomcat", and $TOMCAT_SCRIPT is normally "/usr/sbin/tomcat6". "su -" or "runuser -" runs its command as the specified user, from the specified user's home directory. So this command will change to the "tomcat" user's ID and home directory, then run /usr/sbin/tomcat6. The tomcat6 script eventually launches tomcat itself.

The tomcat user's home directory should be the same as CATALINA_BASE. In short, the "su" or "runuser" command here is what sets the current working directory to CATALINA_BASE.

The init.d script isn't formally part of tomcat; it's supplied by the package maintainer, and it can be different from one system to another. On my Ubuntu 13 system, /etc/init.d/tomcat6 contains a command to cd to $CATALINA_BASE.

Tomcat's own startup scripts (bin/startup.sh and so on) don't set a working directory. When I launch tomcat 6 or tomcat 7 directly using its own startup script, it just inherits the working directory that I ran it from.

Remember that on Linux, you can see any process's actual current directory by checking /proc/<pid>/cwd.

Set Tomcat 7 working directory per webapp?

It is not possible to change the working directory for each web application. The process has a "working directory", and changing that might be problematic, depending upon the server software you are using (Tomcat itself doesn't care, but other app servers such as Weblogic might).

Each application has its own "work" directory when running under Tomcat: if you fetch the value of the context attribute javax.servlet.context.tempdir, you'll find a java.io.File instance that points to a context-specific working directory.

Unfortunately, when simply opening a file like this:

FileInputStream in = new FileInputStream("myfile");

Only the first of the two concepts above is in play: the file will be loaded from the current working directory of the process.

You can try setting the working directory when launching Tomcat, but it will only work for a single application (if you have multiple applications behaving as described above). Here's how you'd do that:

$ cd path/to/web/application
$ $CATALINA_HOME/bin/startup.sh

That will set the working directory to path/to/web/application. Tomcat will do nothing to change that working directory.

If you have multiple applications that all behave this way, one way to get around that would be to simply launch multiple Tomcat processes -- one for each web application -- living in their own working directories. Of course, you'll need a reverse-proxy out front to proxy client requests to the right Tomcat back-end based upon the URL pattern (or whatever), but you should probably have a reverse-proxy anyway for stability and fault-tolerance, anyway.

If you have access to the source code, it would in fact be best to modify it as you suggested in your original posting (albeit using a leading / just to be precise). Even better, perhaps use a servlet or context <init-param> to specify the location of the file, in case you want to move it around somewhere else. Modifying the source code for this purpose shouldn't require any long engagement with some off-shore company... just go edit the file and fix it in 30 seconds.

how to get relative path of current directory in tomcat from linux environment using java

Your problem is that you don't know what the "current" directory is. If you start Tomcat on Linux as a service, the current directory could be anything. So new File(".") will get you a random place in the file system.

Using the system property catalina.base is much better because Tomcat's start script catalina.sh will set this property. So this will work as long as you don't try to run your app on a different server.

Good code would look like this:

File catalinaBase = new File( System.getProperty( "catalina.base" ) ).getAbsoluteFile();
File propertyFile = new File( catalinaBase, "webapps/strsproperties/strs.properties" );

InputStream inputStream = new FileInputStream( propertyFile );

As you can see, the code doesn't mix strings and files. A file is a file and a string is just text. Avoid using text for code.

Next, I'm using getAbsoluteFile() to make sure I get a useful path in exceptions.

Also make sure your code doesn't swallow exceptions. If you could have seen the error message in your code, you would have seen instantly that the code tried to look in the wrong place.

Lastly, this approach is brittle. Your app breaks if the path changes, when a different web server is used and for many other cases.

Consider extending the webapp strsproperties to accept HTTP requests. That way, you could configure your app to connect to strsproperties via an URL. This would work for any web server, you could even put the properties on a different host.

What is a working directory in Intellij IDEA

This is the directory that is set as the Java user.dir system property. If you have any code that creates relative files or directories, it will be relative to this directory. So for a well designed application (i.e. resolves resources from the classpath and is configurable for output directories) this will not be a factor. There is also some importance to this value in maven projects, especially multi-module maven projects. This directory specifies the directory IDEA will read the POM from.

If you are unflamilar with what the Java user.dir is, there is some discussion available here and in the class level Javadoc for the File class.



Related Topics



Leave a reply



Submit