Submitted On 29-JAN-1998
jglick
Acknowledging that a global VM chdir() call is
probably extremely evil for all sorts of reasons,
perhaps it would suffice to leave the semantics of
File alone (it is not so bad really, except for
possibly performance); and just introduce an
optional cwd parameter to the System.exec() suite
(where it is otherwise completely impossible to
simulate without a wrapper shell script!)
Submitted On 18-MAR-1998
briandj
This is a definite problem. I am writing a
shell/desktop which is supposed to be capable
of loading third party classes (java apps).
My desktop starts up with its current directory
( "\desktop" ) preset and unchangeable,
when it attempts to load an app in another
directory ( "\appdir" ), it may fail since the app
may assume that the current directory is it's own
directory and attempt to load data or images.
This problem could occur any time that one java
application attempts to load another application
or class.
If Sun/javasoft does not tend to this problem,
many people will start writing proprietary native
code to get around it. Soon nobody will be
adhering to the notion of 100% pure java.
- Possibilities: -
How about having a separate modifiable "current
directory" for each thread.
If you do not want to add the ability to change
the the current directory, then perhaps you should
remove the whole concept of a "current directory".
It would be nice if you could at least set the
current directory when launching or executing
the JVM. Perhaps you could add a new command
line parameter.
Submitted On 10-APR-1998
klni
Since it is possible to change user.dir,
it should have (at least) some effect,
and any limitations should be clearly
documented so save programming/debugging
time. Basically I can understand and
agree with the "Evaluation by
xxxxx@xxxxx 11/10/1997", but my main
complaint is exactly the "Comment from
jglick Thu Jan 29 13:33:03 PST 1998".
Please "introduce an optional cwd
parameter to the System.exec() suite"
into the 1.2 release. Having to write a
lot of _system_dependent_ wrapper
scripts is really NOT 100% pure Java!
Submitted On 27-MAY-1998
javakev
This is really bad - it keeps me from being able to
run a single JVM in my Java server environment. I'd like
to use thread groups to load seperate Java applications
into a single JVM - because our system could be running
MANY apps. This is so foolish - it makes it hard to
treat Java as a 'real' OS abstraction. See
http://www.interstice.com/~kevinh/projects/javafarm
for more info.
Submitted On 30-MAY-1998
bobalex
There is an area where this facility is really important, and another where is
would be a great convenience.
The *really important* area is in setting the cwd of a created process. Without
this facility, the class of programs one might call "scripting" is
significantly hampered. Java is a good way to recast "shell scripts"
in a platform-independent way. But without being able to set the cwd of
executed "commands", some jobs just can't be done. (Notice how
frequently "cd" is performed in existing scripts -- it must be
useful!)
The *great convenience* area is in changing the cwd for use in resolving
relative paths in the current process. Obviously, the cwd is *used* by Java
runtime in performing various File functions, it is frustrating that it can't
be manipulated. (Interestingly, setting the property "user.dir"
*does* affect the outcome of File.getAbsolutePath().) It's often possible to
work around this shortcoming, but there are times when it's not: when invoking
a 3rd-party Java class which references a file by relative reference and would
like explicit control of which directory is accessed.
My vote: in agreement with jglick, definitely provide a way to set the cwd in
an exec'd process. I would also support having a way to change the cwd in the
local process. This is one of those "empower the programmer" vs.
"protect her from herself" issues, and I generally prefer
empowerment.
Submitted On 21-JUN-1998
tbreuel
It is precisely because the VM depends on all sorts
of ways on the current working directory that a
straightforward "chdir" call is important.
This isn't a question of making applications a
little more efficient, it's a question of letting
me write Java development tools that behave "right".
If you don't want to provide a global "chdir" call,
then the compiler, for example, should require
absolute pathnames for everything (and it should
work properly with absolute pathnames, the 1.2b3
compiler doesn't). But the
current situation where all sorts of runtime state
depend on the working directory of the process
but the working directory cannot be changed is
the worst of both worlds.
If, in addition, you want to introduce a notion of
a "per thread working directory" or "per thread
pathname prefix", that's fine.
As a separate notion, it is also really important
to be able to set the working directory of newly
created processes. This should be separate from
setting the working directory of the current
process destructively before the exec
(although it isn't in all operating systems).
Submitted On 14-JUL-1998
BenPeacock
Here are a couple of workarounds I am using that may be helpful:
1) Use this method to change the working directory for a call to
Runtime.exec() on Windows NT and Unix. It pops up a command prompt
window on Windows if a command-line program is launched. This can
be minimised if launched using "start /min /wait <command>".
public static Process execute( String command, java.io.File directory )
throws java.io.IOException
{
if ( System.getProperty( "os.name" ).startsWith( "Windows
NT" ) )
return Runtime.getRuntime().exec( new String[] {
"cmd /c " + directory.getAbsolutePath()
.substring( 0, directory.getAbsolutePath().indexOf(
":" ) ) +
": && cd " + directory.getAbsolutePath() + "
&& " + command } );
else // assume Unix
return Runtime.getRuntime().exec( new String[] {
"/bin/sh", "-c",
"cd \"" + directory.getAbsolutePath() + "\";
" + command } );
}
2) Use this class instead of File if using a relative file path and
manipulating the system property user.dir. This class treats a
relative file path as relative to the current value of user.dir.
(Does not address multiple thread issues!)
import java.io.File;
public class RelativeFile extends File
{
public RelativeFile( String path ) {
super( path ); }
public RelativeFile( String path, String name ) {
super( path, name ); }
public RelativeFile( File dir, String name ) {
super( dir, name ); }
public boolean exists() {
return new File( getAbsolutePath() ).exists(); }
public boolean canWrite() {
return new File( getAbsolutePath() ).canWrite(); }
public boolean canRead() {
return new File( getAbsolutePath() ).canRead(); }
public boolean isFile() {
return new File( getAbsolutePath() ).isFile(); }
public boolean isDirectory() {
return new File( getAbsolutePath() ).isDirectory(); }
public long lastModified() {
return new File( getAbsolutePath() ).lastModified(); }
public long length() {
return new File( getAbsolutePath() ).length(); }
public boolean mkdir() {
return new File( getAbsolutePath() ).mkdir(); }
public boolean renameTo( File dest ) {
return new File( getAbsolutePath() ).renameTo( dest ); }
public boolean mkdirs() {
return new File( getAbsolutePath() ).mkdirs(); }
public String[] list() {
return new File( getAbsolutePath() ).list(); }
public boolean delete() {
return new File( getAbsolutePath() ).delete(); }
}
Submitted On 25-SEP-1998
moxy
What about having user.relativedir which is resolve to a user.dir when the VM
is started. Then if user.dir changed update user.relativedir to keep the same
directory when resolved using user.dir. Also all relitave directory should be
based off user.relativedir so that if user.dir changed the all the relative
directories would still work. This would solve the problems with relative
directories and allow user.dir to be changed as well.
Submitted On 08-DEC-1998
gback
BenPeacock is wrong. Forking off a shell that
executes a cd command has not impact on the
working directory of the JVM.
Submitted On 08-DEC-1998
gback
I do agree that chdir the complete VM would be
undesirable.
However, I do not follow the argument about one
more piece of mutable global state. If it is desired that File objects remain
immutable in the
sense that even those constructed with a relative
pathname always refer to the same file, then the relative pathname must be
resolved against the current user.dir at construction time. Whether
or not this is desirable or not, I don't know,
but why is this seen as a problem?
Also, has this been fixed in 1.2, pardon me
Java2? Note that Mac's MRJ apparently interprets
changes in user.dir.
- Godmar
Submitted On 08-DEC-1998
pcbeard
Here's my current workaround. In my Java Shell program
(http://www.vmeng.com/beard/JShell/JShell.sit.bin) I simply replace the
standard File, FileInputStream, FileOutputStream, and RandomAccessFile classes
with versions that always expand relative pathnames relative to the
"user.dir" property before calling native methods. This works because
each tool that runs in my system runs in its own thread group (aka ToolContext),
which provides a context for I/O streams, and properties. Each tool also gets
its own copy of the venerable System class, so it has unique static variables
for System.in/out/err/properties. When a new tool runs, it gets a copy of the
properties of its parent (usually a shell). Thus, if a particular shell running
in my system changes its "user.dir" property, only it, and newly run
child tools see the change.
Submitted On 08-DEC-1998
pcbeard
By the way, my aforementioned workaround is not necessary on the Mac OS Runtime
for Java (MRJ) because "user.dir" is live. The native methods call
System.getProperty() to determine the current working directory, mainly because
there's really no such thing as a current working directory on the Mac OS
(unless you count SetVol/GetVol which are essentially deprecated).
Submitted On 08-DEC-1998
gback
Another comment: make the submission form
bigger. It's almost impossible to edit anything
in here. I just read what I submitted a few minutes ago; people must think I'm
a total dyslexic.
Submitted On 26-APR-1999
Ray Burns
I believe adding general chdir functionality to Java would be a mistake. chdir
can be an effective optimization in some cases, but it is _very_ frequently
abused. Lazy programmers use the "current directory" to pass a path
name around implicitly. This is a hack, and it fails miserably when two
independent applications are running in the same VM & sharing the same
threads.
Java should stay pure in this regard.
System.exec() is the only exception to this rule -- some legacy applications
require a specific current directory.
Submitted On 28-MAY-1999
kaltenba
This same bug/RFE is covered in may other bug reports
4156278 seem to be the most discussed and most voted
for. 4156278 also provides a list of related bug reports.
Both this and 4156278 are in the top 25 RFE's, but they
are separate reports they don't carry a combined vote
tally.
Submitted On 31-JUL-1999
tar
The most annoying part of this entire issue is the
mismatch between the use of the current "user.dir" system
property in the construction of absolute pathnames
from relative ones and the use of the original value
of "user.dir" when resolving relative pathnames for all
other java.io.File operations. Could you at least make
the java.io.File class internally consistent in this regard?
That would certainly make it easier for programmers to
understand what is happening in the system.
A note in the java.io.File documentation that changing
the "user.dir" system property won't affect (except maybe
on MRJ?) the resolution of relative pathnames -- or a
mention that the effects are VM dependent would also be
useful.
Submitted On 14-MAR-2000
krab
Another solution would be to enable the installation of a
file-name resolver, much like a Factory object, so that a
Java shell can intercept before a given file is opened.
Submitted On 19-OCT-2000
abies
What is really needed is way to specify working directory
for subprocesses. Inside java application everything can be
done by hand and should be done so (having static variable
for all VM which is randomly changed by various threads is
not a good idea).
Submitted On 10-NOV-2000
jonase
I am writing a native implemetation for unix that change
directory
separately for native threads. This is of course a
workaround to the
current immaturity in java, and generatres big
incompatbility to
diffrent thread models. This is a part of making a runtime
VM-demon for all
java execution... wich makes java a lot faster, and provides
other runtime bennefits I might add.. (...the bennefits from
smalltalk)
Submitted On 14-NOV-2000
Warith
I have a .jar file app which sets the current working
directory to the directory that the jar file is physically
located in, and it works perfectly. (As long as the jar
file is the ONLY thing in the class path) Here is the line
of code:
System.setProperty( "user.dir", new File( new File(
System.getProperty( "java.class.path" ) ).getAbsolutePath
() ).getParent() );
The reason for having two nested File constructors is to
get the ABSOLUTE path from the RELATIVE inner one, and use
this to construct an absolute File reference to obtain the
parent directory from.
I tried this with only a single File constructor and it
worked fine on Windows systems but failed on *nix systems,
must be a different implementation of how File resolves
path names under the *nix JVM.
Submitted On 01-JAN-2001
fancellu
3 years and counting...
Its now 2001. Is sun aiming for a 5 year turnaround?
Bravo!
Submitted On 31-JAN-2001
HolgerK
As an interim solution you might want to try
a workaround using JNI (tested unter Linux 2.2.13 with
JDK 1.3) <a
href="http://www.klawitter.de/java">http://www.klawitter.de/java</a>.
Submitted On 29-JUL-2001
amosshapira
I encountered the need for a chdir(2) when I wanted to run
Jakarta Tomcat with the right "conf" directory under the
current one. I can build a full path name of the
configuration file from the current directory + the
relative path from here, but relative paths read from the
xml file are still broken.
Submitted On 05-AUG-2001
tbreuel
I think the correct way of handling this is for the runtime
to perform its own "current working directory" handling (via
pathname canonicalization and pathname manipulation) and to
make "chdir" a per-thread property. It's either that, or
Java should stop accepting relative pathnames altogether.
Submitted On 24-SEP-2001
igarn
I suggest that a "Context" class be introduced to the IO API. One could then have many contexts, i.e. current directories and calling chdir on some of them would not make global changes in the system. One could then pass such a context as a parameter to a File constructor.
When not supplying a context (in all the code since now) would assume using a default, ummutable one.
Any comments ?
Submitted On 10-NOV-2001
mthornton
The issue of launching a new process in a specified
directory having been fixed, only the efficiency issue
remains. In my opinion this can be addressed without
changing the public API at all. The JVM can monitor the use
of file paths and when something appears more than a few
times, consider making it the working directory. Keeping
the process hidden has several advantages:
1) It can also track usage by the JVM itself (class loaders
etc).
2) On Windows it could manage separate current directories
per drive, if that was worth doing.
3) It is equally easy to adapt to an OS without a notion of
current directory or where that property is a per thread
attribute.
Submitted On 14-DEC-2001
petermantell
Er, mthornton said:
> The issue of launching a new process in a specified
> directory having been fixed
Has it? How?
Submitted On 24-JAN-2002
mthornton
(response to petermantell)
JDK 1.3 added the following method to Runtime:
public Process exec(String command,
String[] envp,
File dir)
where 'dir' specifies the working directory of the new
process.
throws IOException
Submitted On 02-FEB-2002
haustein
I would like to vote AGAINST this "enhancement", but the
voting system does not seem to support this?
Submitted On 28-OCT-2002
bestsss
Please add a feture to vote AgainsT. ChDir is quite a hack
for currently running process, so I would like to vote
against. W/ Runtime.exec(String, String[], File) added
there is no clear reason why ChDir should be implemented and
how multi-thread programs could make use of it.
Submitted On 14-NOV-2002
roedy
With threads, chdir is dangerous unless every thread has its own private inherited default directory. Instead of opening that can of worms, and carrying needless overhead rarely used, perhaps just let user maintain his own default dirs, and merge them with the relative filenames as needed.
Submitted On 01-DEC-2002
kamikaze
I'm another vote against.
If you need to simulate chdir, it is trivial to do:
System.setProperty("user.dir", newdir);
//...
File file = new File(filename).getAbsoluteFile();
Just get in the habit of never, ever using relative Files - the user can
always specify -Duser.dir=somewhere on the command line, which will
raise nine different flavors of hell if you use relative Files.
Sun could change File to be absolute in the constructor, but I don't see
a dire need for it when you can specify it yourself.
-- <a href="http://kuoi.asui.uidaho.edu/~kamikaze/"> Mark Hughes </a>
Submitted On 14-MAY-2003
dkf
There are times when being able to do a chdir() would be
nice, and they are when integrating with particularly crufty
pieces of native code. The rest of the time (and not just in
Java), it is far easier to not rely on the working directory at
all.
Submitted On 09-NOV-2003
cdsmith1
Contrary to the evaluation from 11/10/1997 as posted above,
if this is implemented, it ought to change the real working
directory for the process on those operating systems where
such a thing exists. Introducing an API method called chdir()
that does *not* do so is dangerously misleading, since this
piece of process state is externally visible on most operating
systems.
Submitted On 25-FEB-2004
tschodt
Opposed.
However, the suggestion by igarn seems to address all the
undesireable effects one could get from a plain "chdir()"
implementation.
Submitted On 17-APR-2004
ScottNicol
Happy 7th birthday, RFE.
I'd like to second cdsmith1's comments on 11/9/2003 in that the current working directory is process state, so you can't just "fake" it. One more little example where it is nice to have. Say you have a server running 50 java programs. One of them has gone nuts. You do "top", and you see processes named "java" all the way down the page. Same with ps. How can you tell them apart? current working directory could be the thing.
To do this now means you have to write a shell script (and a batch file, assuming you also want to run on Windows) wrapper. Maybe with an added step of reading a configuration file to find out what the directory should be. Doesn't this seem like a step backwards? I thought I was rid of DOS batch scripts around 1990, but then Java came and I was stuck writing batch files again. Or you could write some trivial JNI code.
What to do with relative files? You can leave them alone, so they are now pointing somewhere else. You can patch them up and make them absolute. You can add classes for absolute and relative files. Whatever happens, I really don't care. It's an implementation detail, just document it and I'll live with it. Surely somebody could come up with something acceptable in 7 years?!? (obviously Sun can't, and don't call them Shirley).
What about systems that don't support chdir? Fail silently, throw and exception, whatever. Just document it.
Submitted On 10-AUG-2004
npavlica
After years of development it's time to start filling in these little gaps. This should have been done years ago.
Submitted On 20-FEB-2005
v_patryshev
Look at this:
[code]
String rootname = "D:\\tmp";
String filename = "testfiles.txt";
String rootfilename = rootname + File.separator + filename;
String expected = "this is a test";
writeToFile(expected, rootfilename);
System.setProperty("user.dir", rootname);
File file = new File(filename);
assertEquals(rootfilename, file.getAbsolutePath());
File rootfile = file.getAbsoluteFile();
assertTrue(rootfile.exists());
assertTrue(file.exists());
[/code]
Does not this validate the case for fixing this at last... 8 years later!
Submitted On 16-MAR-2005
sf_jeff
Absolutely opposed to the idea of changing the runtime for the JRE. It makes function calls like myFile. getAbsolutePath(".") worthless and introduces a lot of bugs in old code. (Unless you WANT to create a sequel to the Millineum bug...). Consider that a very small percentage of the code running in most JVMs is your own...
I applaud the ability to set dir of the JVM on startup and the ability to set the path on a System.Exec(), though.
The Context idea is an interesting one, but lets forget the macaroni code...
hmmm, So a context is something which refers to a location on the hard drive? yeah, we had those things, but where I grew up we called those files... ;-)
Adding the following functions would do for manipulating files in programs, with the explicit understanding that changing a file
Submitted On 16-MAR-2005
sf_jeff
My comment got truncated... here is the rest:
File.ls(); //returns a list of files in the current directory File File.cd(String newd); //returns a file pointing to the new location. Just like String, the File would be immutable and yet programmers would be able to avoid ugly System.Exec() calls. There would be system dependant code in creating the correct path strings in a CD, but it is fairly straightforward and only has to be done once.
Submitted On 27-APR-2005
tgr1
There are plenty of things you can change that would break multithreaded programs. All you need is a warning stating that if you write multithreaded code you might not want to change the cwd. Developers should be treated as if they have a certain amount of understanding and if the docs say this might be a problem in this situation then it is there problem if they shoot themselves in the foot. Don't restrict some because you are worried others may make mistakes.
In addition if this is introduced security must be thought of. If you are writing something like a servlet container you want to stop the servlets contained changing the cwd.
When is this likely to happen?
Submitted On 26-JUL-2005
Ken_Huffman
I need this functionality because I am Runtime.exec() a process that expects to be a particular directory. This cannot be faked with user.dir
Submitted On 10-AUG-2005
abies
Ken - why you don't use 3 parameter exec method then ? Last parameter allows you to specify a working directory (and it is there since java 1.3).
To be honest - is anybody, who is aware of this method, still requesting the chdir ? I don't see a point for it at all, given that you can run any child processes in their own working directories.
Submitted On 10-FEB-2006
garythompson
Just a short though on this. The reason I was interested in this is that if you wan't to write a Java based shell which will execute java programs cwd becomes a problem. For example if you start another java program in the same jvm by calling main then it will get the same working directory because it is in the same jvm. Now you can start another jvm but with the space and time costs of each jvm this is very expensive for a shell type of environment. However, there is an apparent cure. If and when Isolates become available, if we start a light weight Isolates inside a single JVM for each required instance of a JVM and if each isolate can start with a different cwd the problem is mostly cured. There are a few ifs though that the java people need to address...
Submitted On 25-MAR-2006
skybrian
Also note that some of us like to write unit tests for methods that use the current directory in some way and it would be nice not to have to launch a JVM to do this. In general, to support testing, if the user can change a parameter from outside the JVM there should be some way to do it inside the JVM.
The real problem is having a global immutable parameters at all - why should current directories have a one-to-one mapping with processes?
(Of course, another solution would be to make launching a new JVM with the current classpath cheap and easy. ProcessBuilder helps but it's not as nice as a launchJVM method might be, and there's the speed issue.)
Submitted On 09-OCT-2006
Anoter vote on this from someone wanting to test a program that uses the current working directory, from inside Java.
I would be happy with a solution that worked only thread-locally, e.g.,
System#runWithCurrentWorkingDirectory(File,Runnable);
(possibly inherited by new threads).
I agree that a global chdir is too dangerous.
Submitted On 18-JUL-2007
Am I the only one to think that a ThreadLocal chdir could be implemented with one (~20 line) class:
public class ChDir
{
File F_CurrentDir;
public void chdir( File F ) { ... }
public File resolve( File F_Relative ) { ... }
}
and using:
doSomething( CD.resolve( F ) );
rather than:
doSomething( F )
whenever the alternative working directory was needed?
Yeah, so it's not the prettiest or most efficient solution out there, but it can be made application-wide, thread-safe, and static if need be. And how many things in Java's innards rely on "user.dir" but can't be efficiently dispatched to run in another process?
Besides, if we get operator overloading, we can write:
doSomething( CD/F );
(Just kidding! ;^)
Submitted On 25-FEB-2008
Personally, I would find a csh like pushd(), popd(), and dirs()
paradigm alot more useful than a chdir() paradigm. Usually,
when programming, I just want to pushd() over somewhere
else, use relative pathnames, then popd() back when done.
Submitted On 22-APR-2008
trejkaz
Can't you just fix this problem by avoiding calling any native function with relative paths? It seems to me that if you just call getAbsoluteFile() and then use that, the problem goes away as user.dir then works.
The developer can sometimes use this trick to avoid the problem in their own code, but I've witnessed things like loadLibrary failing to find a DLL after the directory is changed underneath by some other native code, and since there is no way in Java to set it back...
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|