I have a war file that I deployed with Tomcat.
I have a Dockerfile and at the end I build a kubernetes pod.
The problem is that if my property files from my app do exist in the path: /usr/local/tomcat/webapps/myapp/WEB-INF/classes/config/ and not in path /usr/local/tomcat/webapps/myapp/WEB-INF/classes/, so the application does not start.
In config I have connection.properties and log4j2.xml.
I set another path by this method:
RUN sed -i -e 's/^shared.loader=$/shared.loader="${catalina.base}/webapps/napgui/WEB-INF/classes/config"/' /usr/local/tomcat/conf/catalina.properties
Everything is fine except log4j2.xml. The values from Kubernetes are overwritten here in the container on log4j but it seems that this path is not good for log4j because in the container logs I receive errors related to the old log4j. From what I understand, he look for the first time in WEB-INF/classes and if can't find any log4j file then it look in WEB-INF/lib and there is the jar with the old log4j, and hence the errors related to the old log4j. Why not consider the one in the new path and what should be done? Thank you
Related
My Spring Boot application (2.1.1.RELEASE) is deployed as a WAR in a Tomcat 8.5 server under a Debian 9 system. It uses, among others, the following files to configure the application :
myApplication.properties (main configuration file for Spring)
log4j2.xml
Both are under src/main/resources.
My question is about how to configure Tomcat and Spring Boot in a way that allow me to have a directory /home/oliver/conf which contains both of these files, in order to override the defaults defined under src/main/resources (which are then in WEB-INF/classes in the exploded WAR).
Below are the steps I've taken.
First, and as a requirement for the project I'm working on, I changed the default Tomcat base directory to point to another place by editing /etc/init.d/tomcat8 :
CATALINA_HOME=/usr/share/tomcat8
CATALINA_BASE=/home/oliver
My /home/oliver/conf folder, which holds the Tomcat and Spring configs, looks like this :
- Catalina/
- context.xml
- web.xml
- server.xml
- ...
- myApplication.properties
- log4j2.xml
- otherAppConfFile.properties
- ...
Because Spring looks for application.properties by default, I'm using the #PropertySource annotation to specify another file :
#SpringBootApplication
#PropertySource({classpath: myApplication.properties})
public class MyApp extends SpringBootServletInitializer {...}
I've tried to add -Dspring.config.location=file:/home/oliver/conf/myApplication.properties to JAVA_OPTS defined in /etc/default/tomcat8, and it works (overrides the embedded file correctly), but for instance if I try to add file:/etc/oliver/conf/log4j2.xml to the previous JVM parameter, it doesn't work.
I read a bit about Spring "environment profiles" but don't wish to use them if possible.
When I launch Tomcat and issue a ps aux | grep tomcat command, I see all the JAVA_OPTS parameters defined as expected, and I also see the following :
-classpath :/home/oliver/conf:/usr/share/tomcat8/bin/.... -Dcatalina.base=/home/oliver -Dcatalina.home=/usr/share/tomcat8
I'm a bit confused about the way Tomcat's classpath and Spring's are related, and how I should solve this issue.
If the classpath I see at launch includes the /home/oliver/conf directory, why are the files inside not overriding the embedded property files (myApplication.properties, log4j2.xml ...) ? Is the folder seen and added to Spring's classpath ?
EDIT :
As a side note, there might be a variety of files under /home/oliver/conf which would need to be taken into account, for instance log4j2.xml + myApplication.properties + keystore.jks so I'm not sure I can rely on -Dspring.config.location and -Dlogging.config entirely.
What I understand from your question is that you are trying to do something like this.
-Dspring.config.location=file:/etc/oliver/conf/log4j2.xml
I think the property spring.config.location is to provide the location of a properties file for configuration and not log4j2.xml.
You can set the location of the log file in myApplication.properties by setting the value for logging.config like
logging.config=file:/etc/oliver/conf/log4j2.xml
Or else you can try
-Dlogging.config=file:/etc/oliver/conf/log4j2.xml
UPDATE
This is what I do in my production systems. Create a file setenv.sh and enter below command.
export JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=/path/to/keystore/keystore.jks -Djavax.net.ssl.trustStorePassword=changeit -Dspring.profiles.active=qa -Dspring.config.location=/path/to/config/ -Dfws_log=/path/to/logfile/location -Xms512m -Xmx1024m -Dsecret.key=somesecretkey"
You can add any number of key value mappings in this file and all of them will be loaded when your tomcat starts.
When I use executable .jar for my project, I can put my application.properties file into same folder as my .jar, and all my property values will be reading from extended application.properties file.
My question is: It is possible to make like this for .war and tomcat server?
[UPDATE]
The answer is: On standalone tomcat you would have to put an application.properties in <tomcat>/bin
Thanks to #Strelok
You can run your application with spring.config.location property set to the path to your properties file using the file: protocol:
# will look for /etc/myapp/application.properties
-Dspring.config.location=file:/etc/myapp/
# will look for /etc/myapp/custom.properties
-Dspring.config.location=file:/etc/myapp/custom.properties
Default config locations that are always searched:
file:./config/
file:./
classpath:/config/
classpath:/
There is a lot more info in the Externalized Configuration section of the documentation for Spring Boot.
Refer Tomcat Class loader for your version of Tomcat to understand what all class loaders are available. Depending upon that, you can add your application properties files to Shared or Common class loader by keeping it in appropriate directory and adding that directory into the class loader entry in catalina.properties file. Tomcat 7 documentation does not show shared classloader, but catalina.properties does have a placeholder for that. If shared works, go for that instead of common Tomcat 7 Classloader
I have my log4j.xml file stored in the project directory but i am getting following error:
log4j:WARN No appenders could be found for logger (p1.Employee).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more
info.
When i palced it in the bin folder Everything works fine. But i dont check in the bin folder in the code repository so i dont want to place it there.
I dont want to use DOMConfigurator.configure("log4j.xml") as well
Below is my Project Stucture.
In a normal Java Project, you can place a log4j configuration file, i.e., a log4j.properties or a log4j.xml, in a resources directory. The resources directory should be on the same level as src. Putting it here, will allow log4j to use the configuration file automatically.
Otherwise, you can set the log4j configuration file to use via a VM option by doing something like:
-Dlog4j.configuration=file:///path/to/log4j.xml
In your case, if you want to place it in the TrailProject project directory, you can do
-Dlog4j.configuration=file:///path/to/TrailProject/log4j.xml
As per the maven java project folder structure, the ideal path to put the config.xml would be in /src/main/resources directory, so for a non maven project you would put it in an equivalent /resources directory.
I have realized that when I run spring booth application, embedded tomcat files extracted under /tmp file.
Periodic cleanup removes this folder so application gives an error.
Is there any way to modify the path, changing from /tmp to /customfolder.
You are looking for the property server.tomcat.basedir, aren't you?
server.tomcat.basedir= # Tomcat base directory. If not specified
# a temporary directory will be used.
I'd like to create a desktop standalone application from my Java/Spring web application. I created MSI-installer that copy all required files to C:\Program Files (x86)\App. But tomcat doesn't have permission and can't write to its own folder. How I can configure tomcat so it would write all app-specific data to other folder? I wouldn't like to install my app to C:\App or user dir.
java.io.FileNotFoundException: C:\Program Files (x86)\App\tomcat\logs\catalina.2016-06-18.log (Access denied)
By setting the environment variable CATALINA_BASE to another directory in your tomcat start script you can configure Tomcat to read/put the working data, configuration and stuff from/to another location. If CATALINA_BASE is set, Tomcat will use the folders %CATALINA_BASE%/bin, %CATALINA_BASE%/conf, %CATALINA_BASE%/logs, %CATALINA_BASE%/temp, etc. for the current instance of Tomcat. This is described in more detail in the Advanced Configuration - Multiple Tomcat Instances section of the RUNNING.txt file in Tomcat's root folder.
If you are planning to ship Tomcat with your application and put all Tomcat files to some user choosable folder you should set CATALINA_HOME to this folder. Tomcat will then use this folder as base directory for everything.
However I think, as you mentioned to ship a standalone application based on Spring, you should seriously take a look at Spring Boot. This will allow you to ship a single fat jar containing all of your application's dependencies (including Tomcat). And this application can simply be started by executing the jar file.
If it's just about the log and temp files, you can set the Java system properties java.util.logging.config.file and java.io.tmpdir in the setenv.bat file under %CATALINA_BASE%/bin to make Tomcat use a custom logging configuration and a different temp dir, respectively. That is the file would look something like this:
set CATALINA_OPTS="-Djava.util.logging.config.file=file:///c:/path/to/log/config.properties"
set CATALINA_OPTS="%CATALINA_OPTS% -Djava.io.tmpdir=c:/path/to/temp/dir"
Find and update all occurrences of "$CATALINA_BASE"/logs/catalina.out to custom path in catalina.sh script.