Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java_binary picks an non-configurable working directory #2579

Closed
dfabulich opened this issue Feb 23, 2017 · 5 comments
Closed

java_binary picks an non-configurable working directory #2579

dfabulich opened this issue Feb 23, 2017 · 5 comments
Assignees
Labels
P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-Java Issues for Java rules under investigation

Comments

@dfabulich
Copy link
Contributor

Consider this git repository. https://github.com/dfabulich/java-binary-runfiles

It contains a blank WORKSPACE and an x subdirectory, containing a one-line "Hello world!" data.txt file and a src/main/java subdirectory containing X.java.

X.java looks in the current directory for data.txt and prints it to the console.

import java.nio.file.*;

public class X {
	public static void main(String[] args) throws Exception {
		Path path = Paths.get("./data.txt").toAbsolutePath();
		String content = new String(Files.readAllBytes(path), "UTF-8");
		System.out.println(content);
	}
}

If I cd to the x subdirectory and bazel run x, it fails:

INFO: Running command line: bazel-bin/x/x
Exception in thread "main" java.nio.file.NoSuchFileException: /private/var/tmp/_bazel_dfabulich/a8d8c5256f8fcb91974f0f58db84c936/execroot/java-binary-runfiles/bazel-out/local-fastbuild/bin/x/x.runfiles/__main__/./data.txt

That line is long, but if you scroll right you'll see it's looking in x/x.runfiles/__main__/./data.txt, but data.txt is really in the __main__/x subdirectory.

In this trivial example, it would be straightforward to change X.java to read from ./x/data.txt instead of ./data.txt, but in my actual environment, the file-read code is shared between multiple projects, so the Java file can't know which subdirectory to use at compile time; this is something that I would learn at runtime.

What I'd want is some way to say in my java_binary declaration, "don't run from the __main__ directory; run from the __main__/x directory."

Is there any way to do this?

Environment info

  • Operating System:
    macOS 10.12.3

  • Bazel version (output of bazel info release):
    release 0.4.4

@iirina
Copy link
Contributor

iirina commented Feb 24, 2017

Hm it should be retrieved from __main__ and not __main__/x, since that is the working directory, defined by where your WORKSPACE file is placed.

the file-read code is shared between multiple projects, so the Java file can't know which subdirectory to use at compile time; this is something that I would learn at runtime

What did you mean by this? Can you elaborate? Isn't the data file always on the same path relative to the directory that contains the WORKSPACE file?

@iirina iirina self-assigned this Feb 24, 2017
@dfabulich
Copy link
Contributor Author

I've provided a more complex example in the complex branch of the git repo. https://github.com/dfabulich/java-binary-runfiles/tree/complex

In the complex branch there are three targets, x, y, and config.

config is a java_library that exposes a static Config#getConfig() method.

import java.nio.file.*;

public class Config {
	public static String getConfig() throws Exception {
		Path path = Paths.get("./data.txt").toAbsolutePath();
		return new String(Files.readAllBytes(path), "UTF-8");
	}
}

X.java and Y.java are basically identical (but please imagine they did different work!)

public class X {
	public static void main(String[] args) throws Exception {
		System.out.println(Config.getConfig());
	}
}

x/data.txt is one line, Hello world! and y/data.txt is a different line, Greetings earth!

So this works:

$ bazel build ...
$ cd x
$ ../bazel-bin/x/x
Hello world!
$ cd ../y
$ ../bazel-bin/y/y
Greetings earth!

But neither bazel run x nor bazel run y work, because they're each looking for data.txt in the current working directory.

@dfabulich dfabulich changed the title java_binary picks an undesirable working directory java_binary picks an non-configurable working directory Feb 24, 2017
@dfabulich
Copy link
Contributor Author

I renamed the ticket from "undesirable" to "non-configurable" (because I actually agree that the default working directory is correct).

Which is to say, what I think I want is some kind of parameter to *_binary targets that launches the binary in a specified subdirectory of the runfiles directory, instead of at the root of the runfiles directory.

Then I could update x/BUILD to say something like:

java_binary(
	name='x',
	srcs=glob(['src/main/java/**']),
	deps=['//config'],
	main_class='X',
	data=['data.txt'],
        run_directory='./x',
)

And then x would be launched from __main__/./x instead of __main__. Does that make sense?

@ulfjack
Copy link
Contributor

ulfjack commented Jul 5, 2017

Related to #3325. Bazel run is specified to run the binary in its runfiles directory. I'm not convinced that we should make this configurable, or change it otherwise. If the file is shared between multiple projects, it's your job to make sure that it's in the same runfiles location in all cases, and I don't see why you can't do that. Actually, expecting a specific working directory for your binary seems odd in the first place - maybe you should put the file into resources, or make sure to resolve the file relative to the location of your binary ($0 in unix terms). What do you want to happen if you run the binary directly?

@meisterT
Copy link
Member

We have no plans to make that directory configurable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-Java Issues for Java rules under investigation
Projects
None yet
Development

No branches or pull requests

6 participants