Content of /opt/scripts/jvm/jvm.script.sh

java -cp ./classes:./lib com.mystuff.bar.foo.myclass &

Content of /etc/init.d/init.script.sh

su scriptuser -c "$home/$program"

/opt/scripts/jvm is symlinked to /data/shellscripts (meaning /data/shellscripts exists as a real directory).

Running the init script fails with cannot find class com.mystuff.bar.foo.myclass but if I su to the same user and run it, it works, why?

When I run su scriptuser -c 'declare -p JAVA_HOME' I get JAVA_HOME not found, but if I su to the user first (using su scriptuser) and run it, I get JAVA_HOME="/java"

This may sound crazy, but it seems to fix the issue if I add a trailing slash to the home variable in the init script.





It almost seems like something environmental is messing with the way the symlinks are being handled.

  • What is the output of declare -p JAVA_HOME? – Hauke Laging Nov 24 '14 at 21:28
  • @HaukeLaging When I run su scriptuser -c 'declare -p JAVA_HOME' I get JAVA_HOME not found, but if I su to the user first and run it, I get JAVA_HOME="/java". – Gregg Leventhal Nov 24 '14 at 21:49
  • 1
    Please edit your question to add extra information, it is hard to read and easy to miss in the comments. – terdon Nov 24 '14 at 23:48
  • "but if I su to the same user and run it, it works" – How do you do that, with su scriptuser or with su - scriptuser? – Hauke Laging Nov 25 '14 at 14:26
  • I become scriptuser via su scriptuser. This seems to work fine. – Gregg Leventhal Nov 25 '14 at 14:36

It's a confusing question with the paths and su'ing. When you run this command:

$java -cp ./classes:./lib com.mystuff.bar.foo.myclass

And get 'class not found', that means java is not able to find that class in ./classes or ./lib. If you either

a) use absolute paths, or b) cd to the right place before running the command (su scriptuser -c "cd $home ; ./$program")

it will work more reliably.

As for why adding a "/" to home makes a difference, that does seem very strange. You could break out strace/truss and see what system calls the command is making. This answer quotes from the posix spec:

How linux handles multiple path separators (/home////username///file)

and says "For programs that act on a directory entry, if foo is a symbolic link to a directory, then passing foo/ is a way to make the program act on the directory instead of the symbolic link."

| improve this answer | |
  • I am not confused about that, I am sure you are right, but I only have control over the init script, not the bash script which calls the JVM. I understand that class not found is because the relative pathing in the class path is not working as expected. What I am confused about is why does it make a difference if I su to the user and run the jvm script versus calling the script with su USER -c script if my working directory is the same in both cases. – Gregg Leventhal Nov 25 '14 at 15:53
  • Not saying you're confused, meant to say the question is confusing with all the paths and su'ing ;-) I've edited my answer to suggest a way to make it the same no matter what, as well as added a link to another question that may explain the difference with the extra slash. – Ian McGowan Nov 26 '14 at 6:53
  • Thanks for your input! Because of my inability to edit the called script, I am going to chalk this up to environmental issues and relative pathing. – Gregg Leventhal Dec 1 '14 at 16:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.