This is just an assumption, but I'm following the log of catalina.out and it looks like every time I would expect a value from an environment variable there is nothing. For example:
java.io.FileNotFoundException: /logs/adminLog.log (No such file or directory) where it should go to $CATALINA_BASE/logs/adminLog.log and $CATALINA_BASE=/var/lib/tomcat6
I've set the environment variables this webapp uses as system wide in the /etc/environment file. I've checked and after restarting they are still there. But tomcat insists of reading blanks.
Any ideas of why this is happening? Am I missing something?
You should put tomcat / webapp specific environment variables into setenv.sh in tomcat's bin directory. Create one if it does not exists.
Depends on how you start Tomcat up. Let us say you are starting as user 'test' (assuming unix machine.). Login as 'test' and check environment variables are there in your environment with the 'env' command.
If it is there then Tomcat when started from that shell, with tomcat/bin/startup.sh will be able to read them.
Now, Tomcat will only read variables it understands. If you are setting your own, then your application needs to read them.
Related
I'm a bit confused on this one. It's working locally on Windows, but when I deploy to AWS EC2 with Apache Tomcat installed and Environment Variables configured it's not working. I'm getting the error;
java.sql.SQLException: The url cannot be null
This can only be coming from the bit of code that is trying to connect to the database, i.e. the Database Connection URL is NULL, which would mean that the .war file isn't picking up the Environment Variable correctly for some reason via the code;
System.getenv("myEnvVar_databaseConnectionURL");
What can I do to debug what is going on here? Seems like this should just be working, but isn't. My gut feel is telling me this is some weird Linux Environment Variable thing which is based on the user that is running, i.e. some kind of Global VS per-user Environment Variable thing. But that's just a guess that I need to dig into a little more. i.e. root Environment Variables VS {Tomcat User X TBC what this is} Environment Variables etc.
I can see the Environment Variables when SSH'ing in as 'root' and running;
printenv | myEnvVar_databaseConnectionURL
Yet when doing a basic command in the deployed code, the output is NULL;
System.out.println("URL: " + System.getenv("myEnvVar_databaseConnectionURL"));
This is when I run the command to print the Tomcat output from AWS EC2 as;
journalctl -u tomcat -f
Posting this question while I investigate further.
Environment variables are not shared across sessions, and they are not shared across user accounts in Linux. Just because you can see an environment variable when logged in as root doesn't mean the tomcat process, running as the tomcat user, can see the same environment variables. If you see an environment variable automatically there when you login, it is because one of the scripts your shell executes as part of your session creation is setting up those environment variables.
Since you didn't provide any details at all as to how you are setting the environment variable, I can't point out what you are doing wrong, or explain in any more detail why your current solution isn't working.
The best solution for setting environment variables for Tomcat is to add them to a $CATALINA_BASE/bin/setenv.sh script. Where the exact location of $CATALINA_BASE on your system is dependent on the flavor of Linux you are using (Ubuntu, RedHat, etc.).
I have set environment variable by executing the command
export test=abcd
I can see test=abcd when I run printenvcommand
I have deployed a springboot.jar application and I am passing the JAVA_OPTS from the springboot.conf file.
JAVA_OPTS='-Dspring.profiles.active=aaa -Denv=$test'
I started the app by service springboot start . When I check the process, env variable doesn't have the value of $test environment variable.
/usr/bin/java -Dsun.misc.URLClassPath.disableJarChecking=true -Dspring.profiles.active=aaa -Denv=.
How can I access the environment variable in the conf file? I read somewhere the environment variables will be stripped off when run as service. Basically I want to run as service springboot start which internally executes the below command
java -Dspring.profiles.active=aws -Denv=${whatever is set for env environment variable} -jar springboot.jar
I have tried the below configurations but nothing worked
JAVA_OPTS='-Dspring.profiles.active=aaa -Denv='$test
JAVA_OPTS='-Dspring.profiles.active=aaa -Denv='${test}
JAVA_OPTS='-Dspring.profiles.active=aaa -Denv=${test}'
JAVA_OPTS="-Dspring.profiles.active=aaa -Denv=$test"
Be careful about your quotes. Assuming that you use a "normal" shell, variables won't be substituted in single quotes.
java -Dspring.profiles.active=aws -Denv="$myvariable" -jar springboot.jar should lead to env being available in the JVM, no matter if you run it as a service or not.
If you can't get it to work, try to specify a hard coded value like this java -Dspring.profiles.active=aws -Denv=foo -jar springboot.jar. If env is now available in the JVM, your problem is with your shell or run mechanism. Verify that the user who runs the command (i.e. do you use sudo?) has the variable set.
I had the same problem where my .conf was referencing an environment variable which was in the .bashrc.
What I found out is:
The problem is service strips all environment variables but TERM, PATH and LANG which is a good thing. If you are executing the script directly nothing removes the environment variables so everything works.
https://unix.stackexchange.com/questions/44370/how-to-make-unix-service-see-environment-variables
One solution would be to install your app as a systemd service:
https://docs.spring.io/spring-boot/docs/1.3.x-SNAPSHOT/reference/html/deployment-install.html
Or another way is to use docker and you can specify extra configuration in the docker file, like loading a file which contains your environment variables.
As those solutions where not available in my case I ended up with having the value in the .conf file, like: -Denv=prod
Is it possible to modify Tomcat environment variables and have them picked up by a single reloaded webapp without restarting the whole server?
Let's say we have webapp A and B, and a setenv.sh:
#!/bin/bash
BASE_DIR=/var/srv
JAVA_HOME=/opt/java/jdk1.8.0_45
TOMCAT_DIR=/opt/apache-tomcat-8.0.18
TOMCAT_PORT=8080
SOME_PROPERTY=SOMETHING
If we change SOME_PROPERTY and reload only A, will it catch the new values, or do we need to restart Tomcat?
setenv.sh is not just a configuration file that is read. It is a script that is executed before the tomcat JVM is started, for setting the environment for the tomcat JVM process (a process for the underlying OS). Once that process is started, it is running in a context with this environment variables.
Java can access and mutate system properties (-D parameters to the JVM command line, not to be confused with env variables) through System.getProperty and System.setProperty but it won't be able, on its own, to parse and interpret the shell script(s) that were used to start the JVM process on the host OS.
My suggestion is to create a configuration file, pass the path to this configuration file in an env variable / system property, and reload this file on application startup.
In the documentation the setenv.sh script is listed as a run at startup script. So, you're going to need to restart Tomcat for changes to take hold.
I have a problem. i have 3 tomcat directories in my windows 8 system :
D:/apache tomcat 6/
D:/apache tomcat 6_old/
D:/tomcat6/
The last two folders are old and dirty. I want to use fresh first one; so I am trying to run it.
D:/apache tomcat 6/bin/tomcat6.exe
But strangely windows runs tomcat with configuration and webapps in third one (D:/tomcat6/).
I have set CATALINA_HOME in environment variable; but no effect.
Can you please help. Thanks.
Setting CATALINA_HOME helps, but you have to use startup.bat to start Tomcat, not the tomcat6.exe
You can also do this with a small batch file (I use it that way since I have a lot of tomcat installations on my computer. Here is one of my scripts:
setlocal
cd C:\mock\apache-tomcat-7.0.27\bin
set CATALINA_HOME=C:\mock\apache-tomcat-7.0.27
call startup.bat
Don't see any reason why starting first tomcat starts a different one.
You can remove unused tomcat directories, so that you just have single Tomcat. Also make sure to kill all java/tomcat processes and then start the required one.
Change your CATALINA_HOME
from
D:/tomcat6/
to
D:/apache tomcat 6/
also make sure the following is added to path variable
%CATALINA_HOME%\bin;
I am currently self-studying servlets. It has been cakewalk so far.
I compile my Java programs from command line and I have set the classpath environment variable to D:\Program Files\apache-tomcat-7.0.35-windows-x86\apache-tomcat-7.0.35\lib\servlet-api.jar
so that I do not have to keep entering it over and over again.
However,
my development environment and deployment environment are in different locations (duh). Every time I have to start Tomcat I have to navigate to the bin folder and then call STARTUP.BAT
This is quite annoying.
My question is:
Is there a way so that I can start Tomcat right from the directory where my Java sources are stored ? and avoid the hassle of navigating all the time ?
Something akin to:
E:\Servlet Projects\Project-1\src > startup.BAT and Tomcat would start
Misc:
Operating System: Windows 7 Home Premium 32 bit
Just add the path to Tomcat's bin folder to path environment variable. If a batch/command file is not found in the current folder, then the operating system will look for the file in all paths definied in the path environment variable, in the same order as they're been definied.
Note that this all has completely nothing to do with Java, Servlets, nor Tomcat.