I cannot get a Java application to run correctly when starting it with sudo. My application uses sockets for client connections and also establishes a database connection. If I start the app normally:
java myApp
Everything works perfectly. However, I am trying to get this to be able to be started in the background from a website. So I created a PHP to start it using exec() or passthru(). At first, this seemed to work, but I soon discovered the sockets weren’t actually connecting. Further trial and error led me to the conclusion this was because when I do java myApp, I am logged in as root, but the PHP is not executing as root so there’s security issues.
So I wrote a script, set SUDOERS to allow the script to be run without a password. The script has a single line, java myApp. If I run the script with:
bash myScript
The sockets won’t connect. (Which is to say the applet client hangs trying to connect.) If I try:
sudo bash myScript
The jdbc MySql driver fails to be found. I tried various methods to cure this, including messing with the classpath including using -classpath at compile and / or runtime and putting a copy of the jdbc jar in different places but no luck. Apparently, the sudo environment is different in some subtle way from the logged-in-as-root environment which causes Java to not be able to find the jdbc drivers.
To be clear, I get the jdbc ClassPathNotFound (or no suitable driver error, depending on how I attempt the connection) when I try to run sudo bash myScript while logged in as root. bash myScript works just fine on all counts logged in as root. When I try to run the the either from a PHP script, my client applet can’t connect, which could either be the sockets or jdbc. I am not using an IDE of any sort, just editing with text editors and using javac to compile.
Any suggestions would be appreciated.
Update:
The server is running CentOS, if that helps. I figured the -E was an environment thing (and had guessed environment loss was the cause, but the sudo documentation I was finding wasn’t helping me figure out the solution). I have tried passthru('sudo -i bash /path/to/myScript.sh'); but the java app still fails to start. Nothing shows up in the browser from the passthru. The script now reads:
cd /path/to/app
java myApp
Still toying with it myself; I know I am close to making this work.
After discussion via the comments I understand, that
sudo -Eworks (for your username) – this seems to be the giveaway to what goes on:Your interactive logon has lots of environment variables set up, some of which are needed for execution of Java apps.
Normally,
sudowill “clean up” your environment before switching user – so it will remove the necessary environment variables, butsudo -Ewill keep the environment intact, making it work for you.Now the webserver user (e.g. www-data in Ubuntu) has no environment set up, making
sudo -Ekeep a defective environment.There are a few ways to address that, the easiest being to use
sudo -i– this will run the target user’s shell as if on login.