What exactly setenv.sh is used for in Tomcat? - spring

I searched a lot but couldn't find any useful information about this:
What exactly setenv.sh is used for in Tomcat ?
Let's say we have a REST API (built with Java EE or Spring) which uses some parameters/variables like AWS Credentials, Database Credentials etc.
Does it make sense to parametrize the application with environment variables for these things I mentioned above and put their values to env vars on setenv.sh for each Tomcat instance in case we use more than one instance and with different parameters/variables ?
Or setenv.sh isn't for things like that ?
Thanks in advance

I've only ever seen it used for specifying CATALINA_OPTS, but I noticed that the RUNNING.txt file mentions using it to set JRE_HOME and JAVA_HOME.
RUNNING.txt also states under Advanced Configuration - Multiple Tomcat Instances:
In many circumstances, it is desirable to have a single copy of a
Tomcat binary distribution shared among multiple users on the same
server. To make this possible, you can set the CATALINA_BASE
environment variable to the directory that contains the files for your
'personal' Tomcat instance.
So I guess the answer is that a setenv file can be created for each app and can probably can be used to store credentials, but I don't think that it's commonly used for that purpose.

~/Programs/apache-tomcat-9.0.7/bin/setenv.sh
export CATALINA_OPTS="$CATALINA_OPTS -DENV_TARGET=prod -DMy_Env_Var1=Whatever -DMy_Env_Var2=CapitalOneIsTheBest"
So everything in between "" above in setenv.sh gets set as environmental variables for your applications in Tomcat. To retrieve/use those environmental variables, use this in your Java (Spring) applications:
Ex1) String myWhatever = java.lang.System.getProperties().getProperty("My_Env_Var1");
Ex2) String env= System.getProperties().getProperty("My_Env_Var2");
To change the environmental variable (for example when you are writing unit tests), do this:
System.setProperty("My_Env_Var1", "newEnv");

Related

QUARKUS: Set Environment variable to get value from a linuxcommand

In Quarkus, You can define environment variables that will represent as configuration to your Quarkus app. For example:
DATABASE_PASSWORD=test123
Outside the quarkus app, there is a file that contains a password. The content of this file (being the password) needs to be set to a property in the quarkus app.
Would it be possible to define an environment variable (i.e. a property) that runs a 'cat' command on that file (as the quarkus app is running in a linux environment) and the value is stored in that environment variable?
e.g.
DATABASE_PASSWORD=`cat /var/common/database_secret.txt`
Is this possible? If not would anyone be able to make suggestions for an alternative solution (where we have to have a property whereby the value is from the contents of a file)?
Many thanks.

How can I set max header size from environment variables in a Spring Boot application

I have some SpringBoot 1.5.19.RELEASE services hitting problems because the our Keycloak bearer token is getting big. In the short term, rather than reduce the token size we want to increase the maximum acceptable header size instead.
Lots of stack overflow pages suggest that setting server.max-http-header-size=48000 in application.properties should relieve the symptom and it does. I can also successfully use that from the command line as a system property -Dserver.max-http-header-size=48000. But even changing the command line for all of our services is a little tedious as the commmand line is embedded in each docker image so I wondered about an environment variable which can be changed at deployment time...
Spring docs suggest that application.properies can also be overridden from the environment using the RelaxedPropertyResolver allowing e.g. spring.profiles.active to be set from the SPRING_PROFILES_ACTIVE environment variable. This works well and I've used it many times.
But trying my services with an environment of SERVER_MAX_HTTP_HEADER_SIZE=48000, SERVER_MAX-HTTP-HEADER-SIZE=48000, and even SERVER_MAXHTTPHEADERSIZE=48000 results in the default limits being applied - nothing seems to be recognised by Spring.
How can I specify this setting via an environment variable without having to rebuild the docker images etc that run the services?
there seems to be a bug in spring boot 1.5.19. it works for me if I set:
SERVER_maxHttpHeaderSize=48000

Spring boot not picking value from environment variable in windows

I have declared db url, db user and db password in application.properties like this
spring.datasource.url=${SPRING_DB_URL}
spring.datasource.username=${SPRING_DB_USER}
spring.datasource.password=${SPRING_DB_PASS}
This works in Ubuntu 16.04 but it is not working in windows 7, and the web application is not starting and in logs, it is showing,
Driver com.microsoft.sqlserver.jdbc.SqlServerDriver claims not to
accept jdbcurl, ${SPRING_DB_URL}
I tried setting the environment variable with key like this,
spring_datasource_url but that too is not working.
the app is build as war file
Why this works in Ubuntu but not in Windows 7?
From Externalized Configuration So use the key in upper case letters with combination of underscore if needed
If you use environment variables rather than system properties, most operating systems disallow period-separated key names, but you can use underscores instead (for example, SPRING_CONFIG_NAME instead of spring.config.name).

jvm.options IBM LIBERTY

I search a lot on the web, almost all links says define JVM custom variables in jvm.options also placed it on ${server.config.dir}/jvm.options.For example I added a variable called -DAPP_ENV=PROD. But this is getting as NULL after server startup.
Any idea?
It looks like you want to define an environment variable, so you have two options.
1. Use an Environment variable
In this case, you can define an environment variable (like $PATH) and load it in your app. Note this is not a JVM argument, and it will be set in the bin/server shell command used to start the server.
In the file:${server.config.dir}/server.env
Add the following line: APP_ENV=PROD
Access the value with:
System.getenv("APP_ENV"); -> PROD
2. Use a System property
This is what you are trying to do, so I am not sure why it doesn't work for you, but here's how:
In the file:${server.config.dir}/jvm.options
Add the following line: -DAPP_ENV=PROD
Access the value with:
System.getProperty("APP_ENV"); -> PROD
Note that in both cases these values are set at server start-up, and they are not changed dynamically (most Liberty configuration is dynamic). The JVM options and environment are sourced and set during the start script so a restart is required if you want to change either one.
My personal recommendation is go to the server.env route - its more generic and (to me) feels more appropriate since you are trying to influence the execution environment of the process, rather than defining behaviors or configuration of the JVM.

When following 12 factor rule, where do I store configs?

Here is the link 12 factor
I am confused weather if I should store values inside my app.properties file vs environment variable.
App.properties
Memory_Folder_Test = Test
Memory_Folder_Prod = Production
Memory_Folder_Dev = Development
Strong_threshold = 10
Low_Threshold = 2
Username = FirstUser
Password = PasswordSecret
So theoretically where should I put these values in? application.properties or as environment variables? If I did not read wrong the purpose of 12 factor is to remove putting values in properties file and externalize it.
You can store the values in application.properties file, however, spring allows you to override those values using environment variables. Hence, it is a 12 factor compliant.
You store the properties externally using something like spring cloud config. You then use the environment properties to define the configurations (like the url) needed to access cloud config from your applications
I prefer to store environment variables in files, encrypt the files and check the encrypted files into git, via blackbox: https://github.com/StackExchange/blackbox
Blackbox will handle encryption/decryption so that it makes it rather difficult to check the unencrypted creds into your repo. Also, the way openpgp works, you can enable teams of devs to encrypt/decrypt the files.
That project is maintained by StackExchange (aka the guys who run this site). It takes some time figuring out openpgp/gpg (which blackbox depends on), but it has been well worth it for me. I've been using in linux and also in windows (via the windows linux subsystem).

Resources