Create account / Log in

Compatibility with user-provided user.home

Suggestions for additional features for the module editor and Vassal engine.

Moderators: uckelman, Tim M

Compatibility with user-provided user.home

Postby morvael » January 11th, 2010, 6:37 am

I don't know it for sure, but I believe there is a bug in Java that results in Java system property "user.home" to be lost in processes launched from a Java program using ProcessBuilder. All other system properties carry on successfully.

If the user.home property would carry on to new processes as expected user could run Vassal using for example, PortableApps JavaPortableLauncher, thus Vassal settings would be come portable and you could carry Vassal and your favorite games on an USB stick.

The scenario is as follows: you provide a custom home directory via -Duser.home=xxx parameter (this is what JavaPortableLauncher does) to java.exe and it will work in the launched application, but will be reset to default directory if that application will launch another java application via ProcessBuilder (.start();). I have also experience that providing the same -D parameter to ProcessBuilder will result in a failure to launch the app (don't know why).

The workaround for this is to set an environment variable in the ProcessBuilder object that will point to the provided user.home, because you can only set environment variables and not system properties using that class.

Example code:
Code: Select all
  //reading user home, with priority to the environment variable if set
  String user_home = System.getenv("VASSAL_USER_HOME");
  if (user_home == null) {
    user_home = p.getProperty("user.home");
  }
  //launching a process and providing the home
  ProcessBuilder pb = new ProcessBuilder(...);
  pb.environment().put("VASSAL_USER_HOME", user_home); 
  ...
  pb.start();
User avatar
morvael
 
Posts: 84
Joined: July 22nd, 2008, 7:50 pm
Location: Otwock, Poland

Compatibility with user-provided user.home

Postby uckelman » January 12th, 2010, 9:14 pm

Thus spake "morvael":
I don't know it for sure, but I believe there is a bug in Java that results i
n Java system property "user.home" to be lost in processes launched from a Ja
va program using ProcessBuilder. All other system properties carry on success
fully.

Could you write a test case for me demonstrating the problem?

If this really happens, then (1) it should be reported to Sun as a bug,
and (2) I know a simple work-around (I think).

--
J.

_______________________________________________
Messages mailing list
Messages@forums.vassalengine.org
http://forums.vassalengine.org/mailman/ ... engine.org

Post generated using Mail2Forum (http://www.mail2forum.com)
User avatar
uckelman
Site Admin
 
Posts: 8874
Joined: December 10th, 2007, 9:48 am
Location: Durham, England

Postby morvael » January 13th, 2010, 10:03 am

I have posted a simple workaround but if I remember correctly your Mail2Forum software doesn't send parts of posts that are in the "code" section, so here is a repeat for you:

//reading user home, with priority to the environment variable if set
String user_home = System.getenv("VASSAL_USER_HOME");
if (user_home == null) {
user_home = p.getProperty("user.home");
}
//launching a process and providing the home
ProcessBuilder pb = new ProcessBuilder(...);
pb.environment().put("VASSAL_USER_HOME", user_home);
...
pb.start();

I will try to prepare a test case and post it here, I have never posted about bugs at Sun's site.
User avatar
morvael
 
Posts: 84
Joined: July 22nd, 2008, 7:50 pm
Location: Otwock, Poland

Compatibility with user-provided user.home

Postby uckelman » January 13th, 2010, 11:35 am

Thus spake "morvael":
I have posted a simple workaround but if I remember correctly your Mail2Forum
software doesn't send parts of posts that are in the "code" section, so here
is a repeat for you:

//reading user home, with priority to the environment variable if set
String user_home = System.getenv("VASSAL_USER_HOME");
if (user_home == null) {
user_home = p.getProperty("user.home");
}
//launching a process and providing the home
ProcessBuilder pb = new ProcessBuilder(...);
pb.environment().put("VASSAL_USER_HOME", user_home);
...
pb.start();

No, I saw the code you posted before---what I meant was that I have a
workaround in mind for the particular place in AbstractLaunchAction
from which we launch the Player and Editor.

I will try to prepare a test case and post it here, I have never posted about
bugs at Sun's site.

I'm happy to report the bug to Sun myself, so long as I have a test case
which demonstrates the problem.

--
J.

_______________________________________________
Messages mailing list
Messages@forums.vassalengine.org
http://forums.vassalengine.org/mailman/ ... engine.org

Post generated using Mail2Forum (http://www.mail2forum.com)
User avatar
uckelman
Site Admin
 
Posts: 8874
Joined: December 10th, 2007, 9:48 am
Location: Durham, England

Postby morvael » January 13th, 2010, 11:38 am

I'm already filing the bug report, it looks it isn't that hard.

That would actually be two bug reports because there is also issue with -D not working if there is a space in user.home, double quotes work in command line but not for ProcessBuilder.

I will post the links to bugs here.
User avatar
morvael
 
Posts: 84
Joined: July 22nd, 2008, 7:50 pm
Location: Otwock, Poland

Postby morvael » January 13th, 2010, 12:11 pm

The bugs got numbers (internal review ID) #1694942 and #1694943 but are not yet publicly visible.

I have attached a file to this post with source code and compiled class and a bat file that will create the files that you may then compare.

I have tried the code to be simple so I did assume the platform is Windows.

From my description of the first bug actual results:
The following files will be created:
testcase_0_parent.txt
testcase_0_child.txt
testcase_1_parent.txt
testcase_1_child.txt
testcase_2_parent.txt
testcase_2_child.txt
testcase_3_parent.txt
testcase_3_child.txt
testcase_4_parent.txt
testcase_5_parent.txt
testcase_5_child.txt

You may now compare parent and child files with the same number. First two lines will be different, but the rest (it will print out system properties) should be equal, but:

Custom home without space in path:

In case 0, you will see that in the child file the user.home and java.library.path are different (the java.library.path is only altered and won't break anything by being different). The user.home was reset to the default provided by the platform.

In case 1, you will see that only java.library.path is different. The custom user.home was carried through -D option successfully.

In case 2, you will see the same properties as in case 0, but the custom path that was provided through environment variable was correctly carried through (second line of the child file).

Custom home with space in path:

In case 3, the result will be the same as in case 0.

In case 4, you will see the child file was not created, the process failed to launch at all.

In case 5, the result will be the same as in case 2.
Attachments
testcase.zip
Test case source code and compiled version with .bat to test.
(3.15 KiB) Downloaded 227 times
User avatar
morvael
 
Posts: 84
Joined: July 22nd, 2008, 7:50 pm
Location: Otwock, Poland

Compatibility with user-provided user.home

Postby uckelman » January 13th, 2010, 12:16 pm

Thus spake "morvael":
I'm already filing the bug report, it looks it isn't that hard.

That would actually be two bug reports because there is also issue with -D no
t working if there is a space in user.home, double quotes work in command lin
e but not for ProcessBuilder.

I will post the links to bugs here.


I'm not able to reproduce the bug myself:

Parent.java:

import java.io.InputStream;
import java.io.IOException;

public class Parent {

public static void main(String[] args) throws IOException {

final ProcessBuilder pb = new ProcessBuilder(
"java", "-Duser.home=foobar", "Child"
);

final Process p = pb.start();
final InputStream in = p.getInputStream();

final byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) != -1) System.out.write(buf, 0, len);
}
}

Child.java:

public class Child {
public static void main(String[] args) {
System.out.println("user.home = " + System.getProperty("user.home"));
}
}


[juckelma@plataan pb]$ java Parent
user.home = foobar

This is the expected result for the test.

--
J.

_______________________________________________
Messages mailing list
Messages@forums.vassalengine.org
http://forums.vassalengine.org/mailman/ ... engine.org

Post generated using Mail2Forum (http://www.mail2forum.com)
User avatar
uckelman
Site Admin
 
Posts: 8874
Joined: December 10th, 2007, 9:48 am
Location: Durham, England

Postby morvael » January 13th, 2010, 12:23 pm

You have did the part that works, but you have to consider a different scenario to get to the bug.

Provide -Duser.home to the first app that you launch from command line (that's what JavaPortableLauncher does, it also provided custom java.home to it's portable copy of JRE). You would then expect that if you use ProcessBuilder it will copy all system properties from your instance of java to the child, but it will only copy part of them - java.home will be copied while user.home will not.

The first workaround is what you just did, forcibly specify current user.home to child via -Duser.home used as argument to ProcessBuilder but that will work only if the path doesn't contain space (double quotes won't help you).

The second workaround is to use environment variables, which works.

But both ways are workarounds, in that ProcessBuilder documentation promises to carry over all system properties to child app but it does not.
User avatar
morvael
 
Posts: 84
Joined: July 22nd, 2008, 7:50 pm
Location: Otwock, Poland

Compatibility with user-provided user.home

Postby uckelman » January 13th, 2010, 12:35 pm

Thus spake "morvael":
You have did the part that works, but you have to consider a different scenar
io to get to the bug.

Provide -Duser.home to the first app that you launch from command line (that'
s what JavaPortableLauncher does, it also provided custom java.home to it's p
ortable copy of JRE). You would then expect that if you use ProcessBuilder it
will copy all system properties from your instance of java to the child, but
it will only copy part of them - java.home will be copied while user.home wi
ll not.

I disagree. I don't expect system properties to be automatically passed on
to JVMs started as child processes. ProcessBuilder can be used to start any
process, not just another JVM. While the environment variables for the
parent process are copied to the child process, system properties are not
environment variables. In order for a child process which happens to be a
JVM to get system properties from the parent process, they need to be
specified using the -D flag.

So, I think this part is not a bug.

The first workaround is what you just did, forcibly specify current user.home
to child via -Duser.home used as argument to ProcessBuilder but that will wo
rk only if the path doesn't contain space (double quotes won't help you).

I disagree again. If you change "foobar" to "foobar baz" in my test case,
it still works.

The second workaround is to use environment variables, which works.

But both ways are workarounds, in that ProcessBuilder documentation promises
to carry over all system properties to child app but it does not.

Can you point out where in the javadoc it says this? I don't find that.

--
J.

_______________________________________________
Messages mailing list
Messages@forums.vassalengine.org
http://forums.vassalengine.org/mailman/ ... engine.org

Post generated using Mail2Forum (http://www.mail2forum.com)
User avatar
uckelman
Site Admin
 
Posts: 8874
Joined: December 10th, 2007, 9:48 am
Location: Durham, England

Postby morvael » January 13th, 2010, 12:36 pm

Have you run my test case?
User avatar
morvael
 
Posts: 84
Joined: July 22nd, 2008, 7:50 pm
Location: Otwock, Poland

Compatibility with user-provided user.home

Postby uckelman » January 13th, 2010, 12:38 pm

Thus spake Joel Uckelman:
Thus spake "morvael":
You have did the part that works, but you have to consider a different scen
ar
io to get to the bug.

Provide -Duser.home to the first app that you launch from command line (tha
t'
s what JavaPortableLauncher does, it also provided custom java.home to it's
p
ortable copy of JRE). You would then expect that if you use ProcessBuilder
it
will copy all system properties from your instance of java to the child, b
ut
it will only copy part of them - java.home will be copied while user.home
wi
ll not.

I disagree. I don't expect system properties to be automatically passed on
to JVMs started as child processes. ProcessBuilder can be used to start any
process, not just another JVM. While the environment variables for the
parent process are copied to the child process, system properties are not
environment variables. In order for a child process which happens to be a
JVM to get system properties from the parent process, they need to be
specified using the -D flag.

So, I think this part is not a bug.

More specifically: I think this is not a bug in ProcessBuilder. It is
a bug in VASSAL that we don't pass on user.dir to subprocesses. I'll
fix that ASAP.

Are there any other system properties we need to pass on? Should we
pass them *all* on?

--
J.

_______________________________________________
Messages mailing list
Messages@forums.vassalengine.org
http://forums.vassalengine.org/mailman/ ... engine.org

Post generated using Mail2Forum (http://www.mail2forum.com)
User avatar
uckelman
Site Admin
 
Posts: 8874
Joined: December 10th, 2007, 9:48 am
Location: Durham, England

Postby morvael » January 13th, 2010, 12:41 pm

Ok, looks like you have to provide path with spaces inside in quotes while running from windows command line, but without quotes when specifying a parameter to process builder (?!). I also wonder why java.library.path is then modified between parent and child ProcessBuilder, while it should remain the same if PB is not touching system properties.

If you don't consider not copying system properties a bug, then we are back to Vassal and that it should specify -Duser.home in it's launchers so it would be compatible with PortableApps and work from USB stick (or any other cases where users might wish to provide different home path). That would be a Feature Request then.
User avatar
morvael
 
Posts: 84
Joined: July 22nd, 2008, 7:50 pm
Location: Otwock, Poland

Compatibility with user-provided user.home

Postby uckelman » January 13th, 2010, 12:45 pm

Thus spake "morvael":
Ok, looks like you have to provide path with spaces inside in quotes while ru
nning from windows command line, but without quotes when specifying a paramet
er to process builder (?!).

Yes, ProcessBuilder isn't a shell, so doesn't require shell quoting.

If you don't consider not copying system properties a bug,

I don't see how it could be a bug. In order to copy system properties
reliably, ProcessBuilder would have to somehow know that what it's
starting is another JVM. How could it know that? E.g., what if it's
running a custom JVM called 'foo'? There's no way to detect this
reliably, which is why I suppose Sun left it up to the API user to
handle.

then we are back t
o Vassal and that it should specify -Duser.home in it's launchers so it would
be compatible with PortableApps and work from USB stick (or any other cases
where users might wish to provide different home path). That would be a Featu
re Request then.

Thanks for finding the problem. It will be fixed for 3.1.14.

--
J.

_______________________________________________
Messages mailing list
Messages@forums.vassalengine.org
http://forums.vassalengine.org/mailman/ ... engine.org

Post generated using Mail2Forum (http://www.mail2forum.com)
User avatar
uckelman
Site Admin
 
Posts: 8874
Joined: December 10th, 2007, 9:48 am
Location: Durham, England

Re: Compatibility with user-provided user.home

Postby morvael » January 13th, 2010, 12:48 pm

uckelman wrote:More specifically: I think this is not a bug in ProcessBuilder. It is a bug in VASSAL that we don't pass on user.dir to subprocesses. I'll fix that ASAP.

Are there any other system properties we need to pass on? Should we
pass them *all* on?


It's all in native ProcessImpl.create method, one would have to look in java native sources to see why it alters some system properties but not others.

I believe user.home is sufficient, how many other system variables do you use, you have to check that and may wish to also copy them. However user.home is the crucial one because that's where Vassal looks for it's files about registered modules, user preferences and so on.
User avatar
morvael
 
Posts: 84
Joined: July 22nd, 2008, 7:50 pm
Location: Otwock, Poland

Compatibility with user-provided user.home

Postby uckelman » January 13th, 2010, 8:28 pm

Thus spake "morvael":
I believe user.home is sufficient, how many other system variables do you use
, you have to check that and may wish to also copy them. However user.home is
the crucial one because that's where Vassal looks for it's files about regis
tered modules, user preferences and so on.


Try the 3.1.14-svn6380 build:

http://www.nomic.net/~uckelman/tmp/vassal/

Does this solve the problem?

--
J.

_______________________________________________
Messages mailing list
Messages@forums.vassalengine.org
http://forums.vassalengine.org/mailman/ ... engine.org

Post generated using Mail2Forum (http://www.mail2forum.com)
User avatar
uckelman
Site Admin
 
Posts: 8874
Joined: December 10th, 2007, 9:48 am
Location: Durham, England

Next

Return to Feature Requests

Who is online

Users browsing this forum: No registered users and 4 guests